Commits

Shashank Bharadwaj committed ca66775 Merge

merge

  • Participants
  • Parent commits c1ee05f, b3a902c

Comments (0)

Files changed (66)

 	<classpathentry kind="lib" path="extlibs/mysql-connector-java-5.1.6.jar"/>
 	<classpathentry kind="lib" path="extlibs/postgresql-8.3-603.jdbc4.jar"/>
 	<classpathentry kind="lib" path="extlibs/servlet-api-2.5.jar"/>
-	<classpathentry kind="lib" path="extlibs/asm-4.0_RC2.jar"/>
-	<classpathentry kind="lib" path="extlibs/asm-commons-4.0_RC2.jar"/>
-	<classpathentry kind="lib" path="extlibs/asm-util-4.0_RC2.jar"/>
+	<classpathentry kind="lib" path="extlibs/asm-all-4.0.jar"/>
+	<classpathentry kind="lib" path="extlibs/asm-commons-4.0.jar"/>
 	<classpathentry kind="var" path="ANT_HOME/lib/ant.jar"/>
 	<classpathentry kind="lib" path="extlibs/antlr-runtime-3.1.3.jar"/>
 	<classpathentry kind="lib" path="extlibs/constantine.jar"/>
 *.rej
 *.swp
 *~
+*#
 # IntelliJ files
 *.ipr
 *.iml
 			<arguments>
 			</arguments>
 		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+				<dictionary>
+					<key>LaunchConfigHandle</key>
+					<value>&lt;project&gt;/.externalToolBuilders/Jython.launch</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
 	</buildSpec>
 	<natures>
 		<nature>org.eclipse.jdt.core.javanature</nature>
             <pathelement path="${extlibs.dir}/stringtemplate-3.2.jar" />
             <pathelement path="${extlibs.dir}/livetribe-jsr223-2.0.5.jar" />
 
-            <pathelement path="${extlibs.dir}/asm-4.0_RC2.jar" />
-            <pathelement path="${extlibs.dir}/asm-commons-4.0_RC2.jar" />
-        	  <pathelement path="${extlibs.dir}/asm-util-4.0_RC2.jar" />
+            <pathelement path="${extlibs.dir}/asm-all-4.0.jar" />
             <pathelement path="${extlibs.dir}/constantine.jar" />
             <pathelement path="${extlibs.dir}/guava-r07.jar" />
             <pathelement path="${extlibs.dir}/jaffl.jar"/>
 
         <path id="test.classpath">
             <path refid="main.classpath"/>
-            <pathelement path="${extlibs.dir}/asm-commons-4.0_RC2.jar" />
+            <pathelement path="${extlibs.dir}/asm-commons-4.0.jar" />
             <pathelement path="${extlibs.dir}/junit-3.8.2.jar" />
             <pathelement path="${exposed.dir}" />
             <pathelement path="${compile.dir}" />
             <zipfileset src="${dist.dir}/${jython.dev.jar}"/>
             <zipfileset src="extlibs/antlr-runtime-3.1.3.jar"/>
             <rule pattern="org.antlr.runtime.**" result="org.python.antlr.runtime.@1"/>
-            <zipfileset src="extlibs/asm-4.0_RC2.jar"/>
-            <zipfileset src="extlibs/asm-commons-4.0_RC2.jar"/>
-            <zipfileset src="extlibs/asm-util-4.0_RC2.jar"/>
+            <zipfileset src="extlibs/asm-all-4.0.jar"/>
             <rule pattern="org.objectweb.asm.**" result="org.python.objectweb.asm.@1"/>
             <zipfileset src="extlibs/guava-r07.jar"/>
             <rule pattern="com.google.**" result="org.python.google.@1"/>

File extlibs/asm-4.0_RC2.jar

Binary file removed.

File extlibs/asm-all-4.0.jar

Binary file added.

File extlibs/asm-commons-4.0.jar

Binary file added.

File extlibs/asm-commons-4.0_RC2.jar

Binary file removed.

File extlibs/asm-util-4.0_RC2.jar

Binary file removed.

File src/org/python/antlr/ast/TypedBoolOp.java

+/* Generated file, do not modify.  See jython/src/templates/typed/README.txt */
+
+package org.python.antlr.ast;
+
+import org.antlr.runtime.Token;
+import org.python.antlr.AST;
+import org.python.antlr.PythonTree;
+import org.python.antlr.base.expr;
+import org.python.antlr.base.stmt;
+import org.python.core.PyObject;
+import org.python.core.PyType;
+import org.python.expose.ExposedGet;
+import org.python.expose.ExposedType;
+
+@ExposedType(name = "_ast.TypedBoolOp", base = AST.class)
+public class TypedBoolOp extends BoolOp {
+
+    public static final PyType TYPE = PyType.fromClass(TypedBoolOp.class);
+
+    public TypedBoolOp(PyType subType) {
+        super(subType);
+    }
+
+    public TypedBoolOp() {
+        super();
+    }
+
+    public TypedBoolOp(PyObject op, PyObject values) {
+        super(op, values);
+    }
+
+    public TypedBoolOp(Token token, boolopType op, java.util.List<expr> values) {
+        super(token, op, values);
+    }
+
+    public TypedBoolOp(Integer ttype, Token token, boolopType op, java.util.List<expr> values) {
+        super(ttype, token, op, values);
+    }
+
+    public TypedBoolOp(PythonTree tree, boolopType op, java.util.List<expr> values) {
+        super(tree, op, values);
+    }
+
+    @ExposedGet(name = "repr")
+    public String toString() {
+        return "TypedBoolOp";
+    }
+
+    public <R> R accept(VisitorIF<R> visitor) throws Exception {
+        return visitor.visitTypedBoolOp(this);
+    }
+
+}

File src/org/python/antlr/ast/TypedUnaryOp.java

+/* Generated file, do not modify.  See jython/src/templates/typed/README.txt */
+
+package org.python.antlr.ast;
+
+import org.antlr.runtime.Token;
+import org.python.antlr.AST;
+import org.python.antlr.PythonTree;
+import org.python.antlr.base.expr;
+import org.python.antlr.base.stmt;
+import org.python.core.PyObject;
+import org.python.core.PyType;
+import org.python.expose.ExposedGet;
+import org.python.expose.ExposedType;
+
+@ExposedType(name = "_ast.TypedUnaryOp", base = AST.class)
+public class TypedUnaryOp extends UnaryOp {
+
+    public static final PyType TYPE = PyType.fromClass(TypedUnaryOp.class);
+
+    public TypedUnaryOp(PyType subType) {
+        super(subType);
+    }
+
+    public TypedUnaryOp() {
+        super();
+    }
+
+    public TypedUnaryOp(PyObject op, PyObject operand) {
+        super(op, operand);
+    }
+
+    public TypedUnaryOp(Token token, unaryopType op, expr operand) {
+        super(token, op, operand);
+    }
+
+    public TypedUnaryOp(Integer ttype, Token token, unaryopType op, expr operand) {
+        super(ttype, token, op, operand);
+    }
+
+    public TypedUnaryOp(PythonTree tree, unaryopType op, expr operand) {
+        super(tree, op, operand);
+    }
+
+    @ExposedGet(name = "repr")
+    public String toString() {
+        return "TypedUnaryOp";
+    }
+
+    public <R> R accept(VisitorIF<R> visitor) throws Exception {
+        return visitor.visitTypedUnaryOp(this);
+    }
+
+}

File src/org/python/antlr/ast/VisitorBase.java

         return ret;
     }
     
+    
+    public R visitTypedUnaryOp(TypedUnaryOp node) throws Exception {
+        R ret = unhandled_node(node);
+        traverse(node);
+        return ret;
+    }
+    
+    
+    public R visitTypedBoolOp(TypedBoolOp node) throws Exception {
+        R ret = unhandled_node(node);
+        traverse(node);
+        return ret;
+    }
+    
     abstract protected R unhandled_node(PythonTree node) throws Exception;
     abstract public void traverse(PythonTree node) throws Exception;
 }

File src/org/python/antlr/ast/VisitorIF.java

     public R visitTypedCompare(TypedCompare node) throws Exception;
     public R visitOptimizedFor(OptimizedFor node) throws Exception;
     public R visitInsertCast(InsertCast node) throws Exception;
+    public R visitTypedUnaryOp(TypedUnaryOp node) throws Exception;
+    public R visitTypedBoolOp(TypedBoolOp node) throws Exception;
 }

File src/org/python/compiler/AdapterMaker.java

     public void build() throws Exception {
         names = Generic.set();
         int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNCHRONIZED;
-        classfile = new ClassFile(myClass, "java/lang/Object", access);
-        classfile.addInterface(mapClass(interfaces[0]));
+        classfile = new ClassFile(myClass, "java/lang/Object", access, mapClass(interfaces[0]));
         addMethods(interfaces[0], new HashSet<String>());
         addConstructors(Object.class);
         doConstants();

File src/org/python/compiler/ClassFile.java

 package org.python.compiler;
 
 import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
 import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.FieldVisitor;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
-
+import org.objectweb.asm.util.CheckClassAdapter;
+import org.python.core.Options;
+import org.python.core.Py;
 import org.python.core.imp;
 
 public class ClassFile
 {
+    private static final boolean DEBUG = false | Options.verbose >= Py.DEBUG;
+
     ClassWriter cw;
+    ClassVisitor cv;
     int access;
     long mtime;
     public String name;
         return new String(c);
     }
 
-    public ClassFile(String name) {
+    public ClassFile(String name, String... interfaces) {
         this(name, "java/lang/Object", Opcodes.ACC_SYNCHRONIZED | Opcodes.ACC_PUBLIC,
-                org.python.core.imp.NO_MTIME);
+                org.python.core.imp.NO_MTIME, interfaces);
     }
 
-    public ClassFile(String name, String superclass, int access) {
-        this(name, superclass, access, org.python.core.imp.NO_MTIME);
+    public ClassFile(String name, String superclass, int access, String... interfaces) {
+        this(name, superclass, access, org.python.core.imp.NO_MTIME, interfaces);
     }
-    public ClassFile(String name, String superclass, int access, long mtime) {
+
+    public ClassFile(String name, String superclass, int access, long mtime, String... interfaces) {
         this.name = fixName(name);
         this.superclass = fixName(superclass);
-        this.interfaces = new String[0];
+        this.interfaces = interfaces;
         this.access = access;
         this.mtime = mtime;
-        
         cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+        cv = DEBUG ? newCheckClassAdapter(cw) : cw;
+        cv.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, this.name, null,
+                this.superclass, this.interfaces);
         methodVisitors = Collections.synchronizedList(new ArrayList<MethodVisitor>());
         fieldVisitors = Collections.synchronizedList(new ArrayList<FieldVisitor>());
     }
         ByteArrayOutputStream baos = new ByteArrayOutputStream(ba.length);
         baos.write(ba, 0, ba.length);
         baos.writeTo(stream);
-        debug(baos);
+        if (DEBUG) {
+            debug(baos);
+            checkClassVerify(ba);
+        }
         baos.close();
     }
 
+    private void checkClassVerify(byte[] ba) {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(System.out);
+        try {
+            CheckClassAdapter.verify(new ClassReader(cw.toByteArray()), false, pw);
+        } catch (Throwable t) {
+            System.err.println("CheckClassAdapter not found");
+            return;
+        }
+        assert sw.toString().length() == 0;
+    }
+
+    public static ClassVisitor newCheckClassAdapter(ClassVisitor cv) {
+        try {
+            return new CheckClassAdapter(cv);
+        } catch (Throwable t) {
+            return cv;
+        }
+    }
+
     private void debug(ByteArrayOutputStream baos) {
         FileOutputStream fos = null;
         try {

File src/org/python/compiler/ConstantifyVisitor.java

 import org.python.antlr.ast.InsertCast;
 import org.python.antlr.ast.Num;
 import org.python.antlr.base.expr;
+import org.python.compiler.typechecker.ArrowType;
 import org.python.compiler.typechecker.DynamicType;
 import org.python.compiler.typechecker.GroundType;
+import org.python.compiler.typechecker.Type;
 
 /**
  * This visitor runs through the AST to identify the following pattern:
 			return rest;
 		}
 		if(node.getInternalTo() == null){
+//			System.err.println(" GONE!");
 			rest.data.internalType = GroundType.LONG;
 			return rest;
 		}
 		if(node.getInternalTo().equals(node.getInternalFrom())){
+//			System.err.println(" GONE!");
 			return rest;
 		}
-		if(node.getInternalFrom() == GroundType.LONG && node.getInternalTo() == DynamicType.Q){
+		if(isPythonBaseType(node.getInternalFrom()) && isDynamicType(node.getInternalTo())){
+//			System.err.println(" GONE!");
 			return rest;
 		}
 //		System.err.println("");
 		return node;
 	}
 
+	private boolean isDynamicType(Type type) {
+		if(type instanceof ArrowType){
+			ArrowType arrow = (ArrowType) type;
+			return arrow.out == DynamicType.Q;
+		}
+		return type == DynamicType.Q;
+	}
+	
+	/**
+	 * Don't insert casts for dynamic python objects which are assigned types.
+	 * 
+	 * @param type
+	 * @return <code>true</code> if the 
+	 */
+	private boolean isPythonBaseType(Type type) {
+		if(type instanceof ArrowType){
+			ArrowType arrow = (ArrowType) type;
+			type = arrow.out;
+		}
+		return type == GroundType.STR || type == GroundType.LONG;
+	}
+
 }

File src/org/python/compiler/ExplicateTypes.java

File contents unchanged.

File src/org/python/compiler/GradualCompiler.java

+package org.python.compiler;
+
+import java.util.Hashtable;
+
+import org.python.antlr.PythonTree;
+import org.python.antlr.base.mod;
+import org.python.compiler.typechecker.AnnotationChecker;
+import org.python.compiler.typechecker.Scope;
+import org.python.compiler.typechecker.TypeError;
+import org.python.compiler.typechecker.Typechecker;
+import org.python.core.CompilerFlags;
+import org.python.core.ParserFacade;
+import org.python.core.Py;
+import org.python.core.PyStaticTraceback;
+import org.python.core.PyTraceback;
+import org.python.core.PythonCodeBundle;
+
+public class GradualCompiler extends LegacyCompiler {
+
+    private static final String TAG = "GradualCompiler";
+    private static AnnotationChecker collector = new AnnotationChecker();
+    private static Typechecker typechecker = new Typechecker();
+
+    private static Scope topscope = Scope.Default;
+
+    @Override
+    public PythonCodeBundle compile(mod node, String name, String filename, boolean linenumbers,
+            boolean printResults, CompilerFlags cflags) {
+        Scope stored = (Scope) topscope.clone();
+        try {
+            if (!cflags.no_typecheck) {
+                Hashtable<PythonTree, Scope> scopes = collector.getScopes(node, topscope);
+                typechecker.typecheck(node, scopes);
+//                Py.writeDebug(TAG, "After Typechecking Pass:\n" + IRPrinter.print(node));
+                node = (mod) ExplicateTypes.makeExplicit(node, scopes);
+                Py.writeDebug(TAG, "After Explicate Pass:\n" + IRPrinter.print(node));
+                node = (mod) ConstantifyVisitor.constantify(node);
+                Py.writeDebug(TAG, "After Constantify:\n" + IRPrinter.print(node));
+            }
+        } catch (TypeError t) {
+            topscope = stored;
+            StringBuilder sb = new StringBuilder();
+            sb.append("Traceback (most recent call last):\n");
+            PythonTree n = t.ast;
+            while (n != null) {
+                sb.append("\tFile " + filename + ", line " + n.getLine() + ", in " + n.getText()
+                        + "\n");
+                n = n.getParent();
+            }
+            PyTraceback tb = new PyStaticTraceback(sb.toString());
+            StringBuilder msg = new StringBuilder();
+            msg.append("(Static) " + t.getMessage() + "\n");
+            msg.append(filename + " (" + name + "): " + t.ast.getText());
+            throw Py.StaticTypeError(msg.toString(), tb);
+        } catch (Throwable t) {
+            throw ParserFacade.fixParseError(null, t, filename);
+        }
+        return super.compile(node, name, filename, linenumbers, printResults, cflags);
+    }
+
+}

File src/org/python/compiler/IRPrinter.java

+package org.python.compiler;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.python.antlr.PythonTree;
+import org.python.antlr.Visitor;
+import org.python.antlr.ast.ClassDef;
+import org.python.antlr.ast.For;
+import org.python.antlr.ast.FunctionDef;
+import org.python.antlr.ast.If;
+import org.python.antlr.ast.Module;
+import org.python.antlr.ast.TryExcept;
+import org.python.antlr.ast.TryFinally;
+import org.python.antlr.ast.While;
+import org.python.antlr.ast.With;
+import org.python.antlr.base.stmt;
+
+/**
+ * A dirty pretty-printer. This code below tries to
+ * 
+ * @author Shashank Bharadwaj
+ * 
+ */
+public class IRPrinter extends Visitor {
+
+    private StringBuilder buf;
+    private String indent;
+    private List<Class> hadBody = new ArrayList<Class>();
+
+    public static String print(PythonTree node) throws Exception {
+        IRPrinter print = new IRPrinter();
+        print.visit(node);
+        return print.toString();
+    }
+
+    public IRPrinter() {
+        buf = new StringBuilder();
+        indent = "";
+        hadBody.add(FunctionDef.class);
+        hadBody.add(ClassDef.class);
+        hadBody.add(With.class);
+        hadBody.add(If.class);
+        hadBody.add(For.class);
+        hadBody.add(While.class);
+        hadBody.add(Module.class);
+        hadBody.add(TryExcept.class);
+        hadBody.add(TryFinally.class);
+    }
+
+    @Override
+    public String toString() {
+        return buf.toString();
+    }
+
+    @Override
+    protected Object unhandled_node(PythonTree node) throws Exception {
+        if (node instanceof stmt) {
+            buf.append(indent + node.toStringTree() + "\n");
+            if (hasBody(node)) {
+                indent += "  ";
+            }
+        } else {
+            buf.append(indent + node.toStringTree() + "\n");
+        }
+        return null;
+    }
+
+    @Override
+    public void traverse(PythonTree node) throws Exception {
+        super.traverse(node);
+        if (node instanceof stmt && hasBody(node)) {
+            indent = indent.substring(0, indent.length() - 2);
+            buf.append(indent + node.toString() + "\n");
+        }
+    }
+
+    private boolean hasBody(PythonTree node) {
+        return hadBody.contains(node.getClass());
+    }
+}

File src/org/python/compiler/Module.java

 import java.lang.invoke.MethodHandle;
 import java.util.ArrayList;
 import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
 

File src/org/python/compiler/ProxyMaker.java

 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 
     public void addClassDictInit() throws Exception {
         // classDictInit method
-        classfile.addInterface(mapClass(org.python.core.ClassDictInit.class));
         Code code = classfile.addMethod("classDictInit", makeSig("V", $pyObj),
             Modifier.PUBLIC | Modifier.STATIC);
         code.aload(0);
         }
         access = Modifier.PUBLIC | Modifier.SYNCHRONIZED;
 
-        classfile = new ClassFile(myClass, mapClass(superclass), access);
+        List<String> ifaces = new ArrayList<String>();
+        // First the two constant interfaces
+        ifaces.add("org/python/core/PyProxy");
+        ifaces.add(mapClass(org.python.core.ClassDictInit.class));
+
+        // now determine which others are to be added
+        for (Class<?> iface : interfaces) {
+            if (iface.isAssignableFrom(superclass)) {
+                continue;
+            }
+            ifaces.add(mapClass(iface));
+        }
+
+        classfile = new ClassFile(myClass, mapClass(superclass), access, ifaces.toArray(new String[0]));
         addProxy();
         addConstructors(superclass);
-        classfile.addInterface("org/python/core/PyProxy");
 
         Set<String> seenmethods = Generic.set();
         addMethods(superclass, seenmethods);
                 Py.writeWarning("compiler", "discarding redundant interface: " + iface.getName());
                 continue;
             }
-            classfile.addInterface(mapClass(iface));
             addMethods(iface, seenmethods);
         }
         doConstants();

File src/org/python/compiler/TransitiveVisitor.java

 import org.python.antlr.ast.Tuple;
 import org.python.antlr.ast.TupleT;
 import org.python.antlr.ast.TypedBinOp;
+import org.python.antlr.ast.TypedBoolOp;
 import org.python.antlr.ast.TypedCall;
 import org.python.antlr.ast.TypedCompare;
 import org.python.antlr.ast.TypedName;
 import org.python.antlr.ast.TypedReturn;
+import org.python.antlr.ast.TypedUnaryOp;
 import org.python.antlr.ast.UnaryOp;
 import org.python.antlr.ast.While;
 import org.python.antlr.ast.With;
         List<expr> bases = visitNodesOfList(node.getInternalBases());
         List<expr> dec_list = visitNodesOfList(node.getInternalDecorator_list());
         Name nameNode = (Name)visitNotNull(node.getInternalNameNode());
-        String name = nameNode == null ? null : nameNode.getInternalId();
-        ClassDef new_node = new ClassDef(node.getToken(), name, bases, body, dec_list);
+        ClassDef new_node = new ClassDef(node.getToken(), nameNode, bases, body, dec_list);
         new_node.data = node.data;
         return new_node;
     }
 
     }
     
+    //Chris's code
+    public Object visitTypedUnaryOp(TypedUnaryOp node) throws Exception {
+        expr operand = visitNotNull(node.getInternalOperand());
+        TypedUnaryOp new_node = new TypedUnaryOp(node.getToken(), node.getInternalOp(), operand);
+        new_node.data = node.data;
+        if(new_node.data.internalType == null)
+        	new_node.data.internalType = DynamicType.Q;
+        return new_node;
+    }
+    
+    public Object visitTypedBoolOp(TypedBoolOp node) throws Exception {
+    	java.util.List<expr> operandList = node.getInternalValues();
+        TypedBoolOp new_node = new TypedBoolOp(node.getToken(), node.getInternalOp(), operandList);
+        new_node.data = node.data;
+        if(new_node.data.internalType == null)
+        	new_node.data.internalType = DynamicType.Q;
+        return new_node;
+    }
+    
+    //End of Chris's code
+    
+    
     @Override
     public Object visitTypedName(TypedName node) throws Exception {
     	return node;

File src/org/python/compiler/TypedCodeCompiler.java

 import org.python.antlr.ast.Subscript;
 import org.python.antlr.ast.Suite;
 import org.python.antlr.ast.TypedBinOp;
+import org.python.antlr.ast.TypedBoolOp;
 import org.python.antlr.ast.TypedCall;
 import org.python.antlr.ast.TypedCompare;
 import org.python.antlr.ast.TypedName;
 import org.python.antlr.ast.TypedReturn;
+import org.python.antlr.ast.TypedUnaryOp;
 import org.python.antlr.ast.cmpopType;
 import org.python.antlr.ast.expr_contextType;
 import org.python.antlr.base.expr;
 import org.python.antlr.base.mod;
+import org.python.antlr.op.Not;
 import org.python.compiler.typechecker.ArrayType;
 import org.python.compiler.typechecker.ArrowType;
 import org.python.compiler.typechecker.DynamicType;
 import org.python.compiler.typechecker.GroundType;
 import org.python.compiler.typechecker.GroundTypes;
+import org.python.compiler.typechecker.ObjectType;
 import org.python.compiler.typechecker.Type;
 import org.python.compiler.typechecker.UnitType;
 import org.python.core.CompilerFlags;
 import org.python.core.Py;
+import org.python.core.PyBoolean;
 import org.python.core.PyComplex;
+import org.python.core.PyFloat;
 import org.python.core.PyFrame;
 import org.python.core.PyFunction;
 import org.python.core.PyFunctionTable;
 import org.python.core.PyInteger;
 import org.python.core.PyObject;
 import org.python.core.PyString;
+import org.python.core.RuntimeCasts;
 import org.python.core.ThreadState;
-import org.python.core.opt.GradualType;
 import org.python.core.opt.InvokeDynamicSupport;
 import org.python.core.opt.MethodHandleHelper;
 import org.python.core.opt.SpecializeCallSite;
-import org.python.core.opt.TypeUtil;
+import org.python.core.opt.Threesome;
 
 import sun.awt.image.BufImgSurfaceData.ICMColorData;
 
-public class TypedCodeCompiler extends OptimizedCodeCompiler {
+public class TypedCodeCompiler extends CodeCompiler {
 
 	class RuntimeValue {
 		int index;
 			mDesc = getDescriptor(arrowType);
 			Suite suite = new Suite(node, node.getInternalBody());
 			suite.data.frameless = node.data.frameless;
-			System.err.println("Suite now has frameless: " + suite.data.frameless);
+//			System.err.println("Suite now has frameless: " + suite.data.frameless);
 			PyCodeConstant genCode = module.codeConstant(suite, name, true,
 					className, null, false, false, node.getLine(), scope, cflags, mDesc);
 //			ArrowType arrowType1 = (ArrowType)node.data.internalType;
 				stackProduce();
 			}
 			stackConsume(2 + argLen); // ts + pyfunction + args
-			// System.err.println("Generating indy jcall: " + node.data.internalType);
-			ArrowType type = (ArrowType) node.data.internalType;
-			StringBuffer sbuf = new StringBuffer();
-			for (Type pType : type.parameters) {
-				sbuf.append(pType.toString());
+//            System.err.println("Generating indy jcall: " + node.data.internalType + " "
+//                    /*+ ((Name) node.getInternalFunc()).getInternalId()*/);
+            // XXX(shashank): Ugly hack! The following check results because
+            // there might be typed functions which were generated in Explicate
+            // (usually because it was a call to a system function which had
+            // Python types such as: abs), and the cast is removed
+            // in Constantify where we realize that we should not have inserted
+            // it in the first place. So we set the type to Dyn, but we need an
+            // arrow type here.
+            if (node.data.internalType instanceof DynamicType) {
+                node.data.internalType = new ArrowType(DynamicType.Q, DynamicType.Q);
+            }
+            ArrowType type = (ArrowType) node.data.internalType;
+            StringBuffer sbuf = new StringBuffer();
+            for (Type pType : type.parameters) {
+                sbuf.append(pType.toString());
 				sbuf.append(",");
 			}
 			MethodType mType = MethodType.fromMethodDescriptorString(getDescriptor(type), null);
 				// XXX: Other types to be handled
 			tmpType = GroundType.JINT;
 			tmp = storeTop(tmpType);
+		} 
+		else if (node.getInternalTargets().get(0).data.internalType != DynamicType.Q &&
+				node.getInternalValue().data.internalType == GroundType.FLOAT) {
+		//		System.err.println("Did stuff at VisitAssign for FLOATS");
+				tmpType = GroundType.FLOAT;
+				tmp = storeTop(tmpType);
 		} else {
 			tmpType = node.getInternalValue().data.internalType;
         	tmp = storeTop(tmpType);
     			code.invokestatic(p(Py.class), "newInteger", sig(PyInteger.class, int.class));
     			return null;
     		}
+        	if(fromType == GroundType.BOOL){
+        		code.invokestatic(p(Py.class), "newBoolean", sig(PyBoolean.class, boolean.class));
+        		return null;
+        	}
+        	if(fromType == GroundType.FLOAT){
+   //     		System.err.println("Casting FLOAT to dynamic");
+        		code.invokestatic(p(Py.class), "newFloat", sig(PyFloat.class, double.class));
+        		return null;
+        	}
     	} else if (fromType instanceof DynamicType){
     		if(toType == GroundType.JINT){
     			code.invokevirtual(p(PyObject.class), "asInt", sig(int.class));
     			return null;
     		}
+    		if(toType == GroundType.BOOL){
+    			code.checkcast(p(PyBoolean.class));
+    			code.invokevirtual(p(PyBoolean.class), "getValue", sig(int.class)); //Could fail as the method is from PyBoolean
+    			return null;
+    		}
+    		if(toType == GroundType.FLOAT){
+    //			System.err.println("Casting dynamic to FLOAT");
+    			code.invokevirtual(p(PyObject.class), "asDouble", sig(double.class));
+    			return null;
+    		}
     		if(toType == UnitType.UNIT){
     			// don't need to do nothing here
     			return null;
     	if((fromType instanceof ArrowType) && (toType instanceof ArrowType)){
     		System.err.println("Function cast from: " + fromType + " to: " + toType + " (rest: " + node.getInteralRest().toStringTree() + ")");
     		code.checkcast(p(PyFunction.class));
-    		code.ldc(new GradualType(fromType, toType).toString());
-    		code.invokevirtual(p(PyFunction.class), "setGradualType", sig(PyFunction.class, String.class));
+    		code.ldc(new Threesome(fromType, toType).toString());
+            code.invokestatic(p(RuntimeCasts.class), "functionCast",
+                    sig(PyFunction.class, PyFunction.class, String.class));
     		return null;
     	}
+        if((fromType instanceof ObjectType) && (toType instanceof ObjectType)){
+//            System.err.println("Object cast from: " + fromType + " to: " + toType + " (rest: "
+//                    + node.getInteralRest() + ")");
+            code.checkcast(p(PyObject.class));
+            code.ldc(new Threesome(fromType, toType).toString());
+            code.invokestatic(p(RuntimeCasts.class), "objectCast",
+                    sig(PyObject.class, PyObject.class, String.class));
+            return null;
+        }    	
     	// FIXME: enable exceptions again!
 //	    throw new IllegalArgumentException("Unsupported cast from: " + fromType + " to: " + toType);
     	return null;
     }
+    //Chris's Code
+    @Override
+    public Object visitTypedUnaryOp(TypedUnaryOp unaryOp) throws Exception {
+    	visit(unaryOp.getInternalOperand());
+    	switch(unaryOp.getInternalOp()){
+    		case Not:
+//    			System.out.println("Native NOT");
+    			if(unaryOp.getInternalOperand().data.internalType == GroundType.FLOAT){
+    				code.dconst_0();
+    				code.mv.visitInsn(DCMPG);
+    			}
+    			Label l1 = new Label();
+    			Label l2 = new Label();
+    			code.mv.visitJumpInsn(IFEQ, l1);
+    			code.iconst_0();
+    			code.mv.visitJumpInsn(GOTO, l2);
+    			code.label(l1);
+    			code.iconst_1();
+    			code.label(l2);
+    			break;
+    		case USub:
+    			if(unaryOp.getInternalOperand().data.internalType == GroundType.FLOAT){
+//    				System.err.println("Native FLOAT negative");
+    				code.mv.visitInsn(DNEG);
+    			}
+    			else{	
+//    				System.out.println("Native negative");
+    				code.mv.visitInsn(Opcodes.INEG);
+    			}
+    			break;
+    		case UAdd:
+//    			System.out.println("UAdd does nothing");
+    			code.nop();
+    			break;
+    		case Invert:
+    			if(unaryOp.getInternalOperand().data.internalType == GroundType.FLOAT)
+    				System.err.println("Should not have FLOAT being inverting, need in type checker!");
+ 		
+//    			System.out.println("Native Inverting");
+    			code.iconst_m1();
+    			code.mv.visitInsn(Opcodes.IXOR);
+    			break;	
+    	}
+    	return null;
+    }
     
+    public Object visitTypedBoolOp(TypedBoolOp boolOp) throws Exception {
+    	for(int i = 0; i < boolOp.getInternalValues().size(); i++)	
+    		visit(boolOp.getInternalValues().get(i));
+    	
+    	switch(boolOp.getInternalOp()){
+    		case And:
+    			if(boolOp.data.internalType != GroundType.FLOAT){
+//	    			System.out.println("Native AND");
+	    			Label l1 = new Label();
+	    			code.swap();
+	    			code.mv.visitJumpInsn(IFNE, l1);
+	    			code.pop();
+	    			code.iconst_0();
+	    			code.label(l1);
+    			}
+    			else{
+//    				System.out.println("Native AND with FLOATS");
+	    			Label l1 = new Label();
+	    			
+	    			code.dup2_x2(); //swap
+	    			code.pop2();
+	    			
+    				code.mv.visitInsn(DCONST_0);
+    				code.mv.visitInsn(DCMPG);
+	    			code.mv.visitJumpInsn(IFNE, l1);
+	    			
+	    			code.pop2();
+	    			
+	    			code.dconst_0();
+	    			code.label(l1);
+    			}
+    			break;
+    		case Or:
+    			if(boolOp.data.internalType != GroundType.FLOAT){
+//	    			System.out.println("Native OR");
+	    			Label l2 = new Label();
+	    			code.swap();
+	    			code.dup();
+	    			code.mv.visitJumpInsn(IFEQ, l2);
+	    			code.swap();
+	    			code.label(l2);
+	    			code.pop();
+    			}
+    			else{
+//    				System.out.println("Native OR with FLOATS");
+	    			Label l2 = new Label();
+	    			
+	    			code.swap2();
+	    			
+	    			code.dup2(); //dup
+	    			
+    				code.mv.visitInsn(DCONST_0);
+    				code.mv.visitInsn(DCMPG);
+	    			code.mv.visitJumpInsn(IFEQ, l2);
+	    			
+	    	   		code.swap2(); //swap
+	     			
+	    			code.label(l2);
+	    			
+	    			code.pop2(); //pop
+    			}
+    			break;	
+    	}
+    	return null;
+    	
+    }
+    
+    
+    
+    
+    //End of Chris's Code
 	@Override
 	public Object visitTypedBinOp(TypedBinOp binOp) throws Exception {
 	    visit(binOp.getInternalLeft());
 	    visit(binOp.getInternalRight());
+	    if(binOp.data.internalType == GroundType.JINT){
             switch(binOp.getInternalOp()){
                 case Mod:
                 case Pow:
                     return super.visitBinOp(new BinOp(binOp.getToken(), binOp.getInternalLeft(),
                                                       binOp.getInternalOp(), binOp.getInternalRight()));
                 case Add:
-                	System.out.println("Native add");
+//                	System.out.println("Native add");
                     code.iadd();
                     break;
                 case Sub:
                     code.mv.visitInsn(Opcodes.IAND);
                     break;
             }
-            return null;
+	    }
+	    else {
+	    	if(binOp.getInternalLeft().data.internalType != GroundType.FLOAT){
+                code.mv.visitInsn(Opcodes.DUP2_X1);
+	    		code.pop2();
+	    		code.mv.visitInsn(Opcodes.I2D);
+	    		code.swap2();
+	    	}
+	    	else if(binOp.getInternalRight().data.internalType != GroundType.FLOAT){
+	    		code.mv.visitInsn(Opcodes.I2D);
+	    	}
+
+	    	
+	    	switch(binOp.getInternalOp()){
+            case Pow:
+            case FloorDiv:
+                  // System.err.println("falling back to binop by pyobjs");
+              	// FIXME: shouldn't there be casts here?
+              	// Oh I know, we should move this logic into Explicate
+                  return super.visitBinOp(new BinOp(binOp.getToken(), binOp.getInternalLeft(),
+                                                    binOp.getInternalOp(), binOp.getInternalRight()));
+            case Add:
+//              	  System.out.println("Native FLOAT add");
+                  code.mv.visitInsn(Opcodes.DADD);
+                  break;
+            case Sub:
+//            	  System.out.println("Native FLOAT sub");
+                  code.mv.visitInsn(Opcodes.DSUB);
+                  break;
+            case Mult:
+//            	  System.out.println("Native FLOAT mul");
+                  code.mv.visitInsn(Opcodes.DMUL);
+                  break;
+            case Div:
+//            	  System.out.println("Native FLOAT div");
+                  code.mv.visitInsn(Opcodes.DDIV);
+                  break;
+	    	
+	    	 }
+	    }
+	    return null;
 	}
 
 	protected Label end_of_suite = null;
 		    load(temporaryType, temporary);
 		    // FIXME: Find a better way to store ints on the frame
 		    if(node instanceof TypedName){
-		    	code.invokestatic(p(Py.class), "newInteger", sig(PyInteger.class, int.class));
+		    	if(node.data.internalType == GroundType.FLOAT){
+	        		code.invokestatic(p(Py.class), "newFloat", sig(PyFloat.class, double.class));
+	       // 		System.err.println("Stored local FLOAT");
+		    	}
+		    	else
+		    		code.invokestatic(p(Py.class), "newInteger", sig(PyInteger.class, int.class));
+	//	    	}
+	//	    	if(node.data.internalType == GroundType.BOOL){
+	//	    		code.invokestatic(p(Py.class), "newBoolean", sig(PyBoolean.class, boolean.class));
+	//	    		System.err.println("Stored local BOOL");
+	//	    	}
 		    }
 		    code.invokevirtual(p(PyFrame.class), "setlocal", sig(Void.TYPE,
                     Integer.TYPE, PyObject.class));
 	 * <code>type</code>.
 	 */
 	private void store(Type type, int index) {
-		// System.err.println("~~~~~~~~storing at " + index + " " + type);
+	  //System.err.println("~~~~~~~~storing at " + index + " " + type);
 	    if(type instanceof GroundType){
 			if(type == GroundType.JINT){
 			    code.istore(index);
 			    return; 
-			} else if(type == GroundType.LONG){
+			} 
+			if(type == GroundType.BOOL){
+				code.istore(index);
+				return; 
+			}
+			if(type == GroundType.FLOAT){
+//				System.err.println("Storing FLOAT at " + index);
+				code.mv.visitVarInsn(DSTORE,index);
+				return;
+			}
+			else if(type == GroundType.LONG){
 			    code.astore(index);
 			    return; 
 			}
 	    } else if (type instanceof ArrowType) {
 	    	code.astore(index);
 	    	return;
-	    }
+	    } else if (type instanceof ObjectType) {
+            code.astore(index);
+            return;
+        }
+
 	    
 	    throw new IllegalArgumentException("Unsupported store operation for type: " + type);
 	}
 			loadFrame();
 			code.iconst(localIndex);
 			code.invokevirtual(p(PyFrame.class), "getlocal", sig(PyObject.class, Integer.TYPE));
-			code.invokevirtual(p(PyObject.class), "asInt", sig(int.class));
+			if(node.data.internalType == GroundType.FLOAT){
+    			code.invokevirtual(p(PyObject.class), "asDouble", sig(double.class));
+//				System.err.println("Loaded local FLOAT");
+			}
+			//if(node.data.internalType == GroundType.JINT){
+			else
+				code.invokevirtual(p(PyObject.class), "asInt", sig(int.class));
+			//	System.err.println("Stored local JINT");
+		//	}
 //			code.invokevirtual(p(PyObject.class), "asInteger", sig(Integer.class));
 		}
 		return true;
 			if(type == GroundType.JINT){
 			    code.iload(index);
 			    return; 
-			} else if(type == GroundType.LONG){
+			}
+			if(type == GroundType.BOOL){
+				code.iload(index);
+				return; 
+			}
+			if(type == GroundType.FLOAT){
+//				System.err.println("Loading FLOAT at " + index);
+				code.dload(index);
+				return;
+			}
+			else if(type == GroundType.LONG){
 			    code.aload(index);
 			    return;
 			}
-	    } else if (type instanceof ArrayType || (type instanceof ArrowType)) {
+	    } else if (type instanceof ArrayType || (type instanceof ArrowType) ||
+	            (type instanceof ObjectType)) {
 //	    } else if (type instanceof ArrayType) {
 	    	code.aload(index);
 	    	return;

File src/org/python/compiler/typechecker/ArrayType.java

 import org.python.antlr.base.expr;
 import org.python.compiler.Code;
 import org.python.compiler.CodeCompiler;
+import org.python.core.Py;
 import org.python.core.PyObject;
 import org.python.core.TypedUtil;
 
 		return Types.ARRAY;
 	}
 	
+    @Override
+    public Type merge(Type that) {
+        if (that instanceof ArrayType) {
+            return new ArrayType(arrayOf.merge(((ArrayType) that).arrayOf));
+        }
+        return super.merge(that);
+    }
+
 	public String toString() {
 		return arrayOf + "[]";
 	}

File src/org/python/compiler/typechecker/ArrowType.java

 import java.util.LinkedList;
 import java.util.List;
 
+import org.python.core.Py;
+
 public class ArrowType extends Type {
 	public static ArrowType Obtain(Type t, Scope scope) throws TypeError {
 		if(t instanceof ArrowType)
 		}
 		return this;
 	}
-	
+
+    @Override
+    public Type merge(Type that) {
+        if (that instanceof ArrowType) {
+            ArrowType other = (ArrowType) that;
+            List<Type> mergedParams = new ArrayList<Type>();
+            List<String> mergedNames = new ArrayList<String>();
+            int i = 0;
+            for (i = 0; i < this.parameters.size() && i < other.parameters.size(); i++) {
+                mergedParams.add(this.parameters.get(i).merge(other.parameters.get(i)));
+                mergedNames.add(this.names.get(i));
+            }
+            ArrowType extra = this.parameters.size() > other.parameters.size() ? this : other;
+            for (; i < extra.parameters.size(); i++) {
+                mergedParams.add(extra.parameters.get(i));
+                mergedNames.add(extra.names.get(i));
+            }
+            return new ArrowType(mergedParams, mergedNames, optionals, this.out.merge(other.out));
+        }
+        return super.merge(that);
+    }
+
 	public boolean subtype(Type t, Scope scope) {
 		if(t instanceof TypeAlias)
 			throw new TypecheckingError();

File src/org/python/compiler/typechecker/DynamicType.java

 package org.python.compiler.typechecker;
 
 public class DynamicType extends Type {
-	public static DynamicType Q = new DynamicType();
-	
-	public static DynamicType Obtain(Type t, Scope scope) throws TypeError {
-		if(t instanceof DynamicType)
-			return (DynamicType) t;
-		if(t instanceof TypeAlias && t.instance(scope) == Types.DYNAMIC)
-			return (DynamicType) scope.lookupAlias((TypeAlias) t);
-		throw new TypecheckingError();
-	}
-	
-	public Type restrict(Type t, Scope scope) {
-		return this;
-	}
+    public static DynamicType Q = new DynamicType();
 
-	public boolean subtype(Type t, Scope scope) {
-		if(t instanceof TypeAlias)
-			throw new TypecheckingError();
-		return t instanceof DynamicType;
-	}
+    public static DynamicType Obtain(Type t, Scope scope) throws TypeError {
+        if (t instanceof DynamicType)
+            return (DynamicType) t;
+        if (t instanceof TypeAlias && t.instance(scope) == Types.DYNAMIC)
+            return (DynamicType) scope.lookupAlias((TypeAlias) t);
+        throw new TypecheckingError();
+    }
 
-	public Types instance(Scope scope) {
-		return Types.DYNAMIC;
-	}
-	
-	public String toString() {
-		return "?";
-	}
-	
-	public boolean equals(Object t) {
-		return t == this;
-	}
+    public Type restrict(Type t, Scope scope) {
+        return this;
+    }
+
+    public boolean subtype(Type t, Scope scope) {
+        if (t instanceof TypeAlias)
+            throw new TypecheckingError();
+        return t instanceof DynamicType;
+    }
+
+    @Override
+    public Type merge(Type t) {
+        return t;
+    }
+
+    public Types instance(Scope scope) {
+        return Types.DYNAMIC;
+    }
+
+    public String toString() {
+        return "?";
+    }
+
+    public boolean equals(Object t) {
+        return t == this;
+    }
 }

File src/org/python/compiler/typechecker/GroundType.java

 		return this;
 	}
 
+    @Override
+    public Type merge(Type that) {
+        if (that instanceof GroundType) {
+            GroundType other = (GroundType) that;
+            if (this == JINT && other == LONG || this == LONG && other == JINT) {
+                return JINT;
+            }
+            // XXX(shashank): None of the other types have subtyping, so this
+            // should be it; super already takes care of the rest.
+        }
+        return super.merge(that);
+    }
+
 	public boolean subtype(Type t, Scope scope) {
 		if(t instanceof GroundType)
 			return type.subtypeCompatibility(((GroundType) t).type);

File src/org/python/compiler/typechecker/GroundTypes.java

 package org.python.compiler.typechecker;
 
 public enum GroundTypes {
-	BOOL, JINT, INT, FLOAT, COMPLEX, STRING;
+    BOOL, JINT, INT, FLOAT, COMPLEX, STRING;
 
-	/**
-	 * Find subtype-compatibility of the Ground Types wrt the other GroundType
-	 * passed in as the parameter.
-	 * <p/>
-	 * Since JINT ~ INT we special-case it.
-	 * 
-	 * @param other GroundType to compare the subtype-compatibility relation
-	 * @return true if this type is sub-type compatible with other, false
-	 *         otherwise.
-	 */
-	public boolean subtypeCompatibility(GroundTypes other) {
-		if (this == INT && other == JINT)
-			return true;
-		return compareTo(other) <= 0;
-	}
+    /**
+     * Find subtype-compatibility of the Ground Types wrt the other GroundType
+     * passed in as the parameter.
+     * 
+     * </p> Since JINT ~ INT we special-case it.
+     * 
+     * @param other
+     *            GroundType to compare the subtype-compatibility relation
+     * @return true if this type is sub-type compatible with other, false
+     *         otherwise.
+     */
+    public boolean subtypeCompatibility(GroundTypes other) {
+        if (this == INT && other == JINT)
+            return true;
+        return compareTo(other) <= 0;
+    }
 }

File src/org/python/compiler/typechecker/ObjectType.java

+package org.python.compiler.typechecker;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ObjectType extends Type {
+
+    public static ObjectType Obtain(Type t, Scope scope) throws TypeError {
+        if (t instanceof ObjectType)
+            return (ObjectType) t;
+        if (t instanceof TypeAlias && t.instance(scope) == Types.OBJECT)
+            return (ObjectType) scope.lookupAlias((TypeAlias) t);
+        throw new TypecheckingError();
+    }
+
+    public List<String> names;
+    public List<Type> types;
+    /** TODO(shashank): There is currently no way to make a class closed. */
+    public boolean isOpen = true;
+
+    public ObjectType(List<String> names, List<Type> types) {
+        assert names.size() == types.size();
+        this.names = names;
+        this.types = types;
+    }
+
+    public Types instance(Scope scope) throws TypeError {
+        return Types.OBJECT;
+    }
+
+    public Type restrict(Type t, Scope scope) {
+        if (t instanceof DynamicType)
+            return DynamicType.Q;
+        if (t instanceof ObjectType) {
+            ObjectType other = (ObjectType) t;
+            List<Type> mergedTypes = new ArrayList<Type>();
+            List<String> mergedNames = new ArrayList<String>();
+            for (int i = 0; i < this.types.size(); i++) {
+                if (i < other.types.size()) {
+                    mergedTypes.add(this.types.get(i).restrict(other.types.get(i), scope));
+                } else {
+                    mergedTypes.add(this.types.get(i));
+                }
+                mergedNames.add(this.names.get(i));
+            }
+            ObjectType objectType = new ObjectType(mergedNames, mergedTypes);
+            return objectType;
+        }
+        return this;
+    }
+
+    @Override
+    public Type merge(Type that) {
+        if (that instanceof ObjectType) {
+            ObjectType other = (ObjectType) that;
+            List<Type> mergedParams = new ArrayList<Type>();
+            List<String> mergedNames = new ArrayList<String>();
+            int i = 0;
+            for (i = 0; i < this.types.size(); i++) {
+                mergedParams.add(this.types.get(i).merge(other.types.get(i)));
+                mergedNames.add(this.names.get(i));
+            }
+            ObjectType extra = this.types.size() > other.types.size() ? this : other;
+            for (; i < extra.types.size(); i++) {
+                mergedParams.add(extra.types.get(i));
+                mergedNames.add(extra.names.get(i));
+            }
+            return new ObjectType(mergedNames, mergedParams);
+        }
+        return super.merge(that);
+    }
+
+    public boolean subtype(Type that, Scope scope) {
+        if (that instanceof TypeAlias)
+            throw new TypecheckingError();
+        if (!(that instanceof ObjectType))
+            return false;
+        if (this.equals(that))
+            return true; // trivially true; a short-cut here.
+        ObjectType other = (ObjectType) that;
+        if (other.types.size() > this.types.size())
+            return false;
+        for (int i = 0; i < this.types.size() && i < other.types.size(); i++) {
+            if (!this.types.get(i).subtype(other.types.get(i), scope))
+                return false;
+            if (!this.names.get(i).equals(other.names.get(i)))
+                return false;
+        }
+        return true;
+    }
+
+    public boolean equals(Object o) {
+        if (o instanceof ObjectType) {
+            ObjectType other = (ObjectType) o;
+            return this.names.equals(other.names) && this.types.equals(other.types);
+        }
+        return false;
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("[ ");
+        for (int i = 0; i < names.size(); i++) {
+            sb.append(names.get(i));
+            sb.append(": ");
+            sb.append(types.get(i));
+            sb.append(", ");
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public Type attributeType(String internalAttr) {
+        if (names.contains(internalAttr)) {
+            Type type = types.get(names.indexOf(internalAttr));
+            return type;
+        }
+        if (isOpen) {
+            return DynamicType.Q;
+        } else {
+            throw new TypecheckingError("Attribute: " + internalAttr + "not found");
+        }
+    }
+}

File src/org/python/compiler/typechecker/Scope.java

 package org.python.compiler.typechecker;
 
 import java.util.ArrayList;
+import java.util.LinkedList;
 
 import org.python.antlr.PythonTree;
 import org.python.antlr.ast.ArrowT;
 import org.python.antlr.ast.GroundT;
 import org.python.antlr.ast.Name;
+import org.python.antlr.ast.ObjectT;
 import org.python.antlr.ast.ParamT;
 import org.python.antlr.ast.TupleT;
 import org.python.antlr.base.ptype;
 			
 			return new ArrowType(args,at.getInternalArgnames(),at.getInternalOptionals(),to);
 		}
-/*	
-		if(n instanceof ObjectT) {
-			ObjectT ot = (ObjectT) n;
-			ObjectType ret = new ObjectType(new LinkedList<String>(), new LinkedList<Type>());
-			for(int i = 0; i < ot.getInternalTypes().size(); i++) {
-				ret.insert(ot.getInternalNames().get(i), Convert(ot.getInternalTypes().get(i), alias));
-			}
-			return ret;
-		}
-		*/
+	
+        if (n instanceof ObjectT) {
+            ObjectT ot = (ObjectT) n;
+            ArrayList<Type> types = new ArrayList<Type>();
+            for (ptype t : ot.getInternalTypes())
+                types.add(convert(t));
+            ObjectType ret = new ObjectType(ot.getInternalNames(), types);
+            return ret;
+        }
 		return DynamicType.Q;
 	}
 	

File src/org/python/compiler/typechecker/TupleType.java

 		}
 		return this;
 	}
+	
+    @Override
+    public Type merge(Type that) {
+        if (that instanceof TupleType) {
+            TupleType other = (TupleType) that;
+            List<Type> mergedTuple = new ArrayList<Type>();
+            int i = 0;
+            for (i = 0; i < this.members.size() && i < other.members.size(); i++) {
+                mergedTuple.add(this.members.get(i).merge(other.members.get(i)));
+            }
+            TupleType extra = this.members.size() > other.members.size() ? this : other;
+            for (; i < extra.members.size(); i++) {
+                mergedTuple.add(extra.members.get(i));
+            }
+            return new TupleType(mergedTuple);
+        }
+        return super.merge(that);
+    }
 
 	public boolean subtype(Type t, Scope scope) {
 		if(t instanceof TypeAlias)

File src/org/python/compiler/typechecker/Type.java

 package org.python.compiler.typechecker;
 
+import org.python.core.Py;
+
 public abstract class Type {
-	public abstract boolean subtype(Type t, Scope scope);
-	public abstract Type restrict(Type t, Scope scope);
-	public abstract Types instance(Scope scope) throws TypeError;
-	
-	public boolean subtypeCompatible(Type t, Scope scope) {
-		Type arb = restrict(t, scope);
-		Type bra = t.restrict(this, scope);
-		return arb.subtype(bra, scope);
-	}
+    public abstract boolean subtype(Type t, Scope scope);
+
+    public abstract Type restrict(Type t, Scope scope);
+
+    public abstract Types instance(Scope scope) throws TypeError;
+
+    /**
+     * Merge the from and to types to find the maximum of the structure of the
+     * two types. This means that we find the most restrictive type of these two
+     * types (Greatest Lower Bound). From the Threesomes with and without blame
+     * paper. This version is without blame tracking.
+     * 
+     * </p> The base case returns this type if the two types are equal. If one
+     * of the types is dynamic, then it returns the other one. If both these
+     * cases fail, then it throws a TypeError.
+     */
+    public Type merge(Type that) {
+        if (this.equals(that) || that instanceof DynamicType) {
+            return this;
+        }
+        if (this instanceof DynamicType) {
+            return that;
+        }
+        throw Py.TypeError("Cannot merge: " + this + " and: " + that);
+    }
+
+    public boolean subtypeCompatible(Type t, Scope scope) {
+        Type arb = restrict(t, scope);
+        Type bra = t.restrict(this, scope);
+        return arb.subtype(bra, scope);
+    }
+
 }

File src/org/python/compiler/typechecker/TypeAlias.java

 package org.python.compiler.typechecker;
 
 public class TypeAlias extends Type {
-	private String name;
-	
-	public TypeAlias(String name) {
-		this.name = name;
-	}
-	
-	public String getName() {
-		return name;
-	}
-	
-	public Types instance(Scope scope) throws TypeError {
-		try {
-			return scope.lookupAlias(this, null).instance(scope);
-		} catch (TypeError t) {
-			return null;
-		}
-	}
+    private String name;
 
-	public Type restrict(Type t, Scope scope) {
-		throw new TypecheckingError();
-	}
+    public TypeAlias(String name) {
+        this.name = name;
+    }
 
-	public boolean subtype(Type t, Scope scope) {
-		throw new TypecheckingError();
-	}
-	
-	public boolean equals(Object o) {
-		throw new TypecheckingError();
-	}
-	
-	public String toString() {
-		return name;
-	}
+    public String getName() {
+        return name;
+    }
+
+    public Types instance(Scope scope) throws TypeError {
+        try {
+            return scope.lookupAlias(this, null).instance(scope);
+        } catch (TypeError t) {
+            return null;
+        }
+    }
+
+    public Type restrict(Type t, Scope scope) {
+        throw new TypecheckingError();
+    }
+
+    @Override
+    public Type merge(Type that) {
+        throw new TypecheckingError();
+    }
+
+    public boolean subtype(Type t, Scope scope) {
+        throw new TypecheckingError();
+    }
+
+    public boolean equals(Object o) {
+        throw new TypecheckingError();
+    }
+
+    public String toString() {
+        return name;
+    }
 }

File src/org/python/compiler/typechecker/Typechecker.java

 		
 		int fstdefault = args.size() - defts.size();
 		
-		System.out.println(at + " <===\n===>" + args);
-		
 		for (int i = fstdefault; i < args.size(); i++) {
 			Type cvt = scope.unroll(at.parameters.get(i));
 			Type deft = scope.unroll((Type)visit(defts.get(i-fstdefault)));
 		return ret;
 	}
 	
-	public Object visitAssign(Assign node) throws Exception {
-		Object ret = unhandled_node(node); 
-		for(expr lhs : node.getInternalTargets()) {
-			ret = assign(lhs, scope.unroll((Type) visit(node.getInternalValue())), node);
-		}
-		
-		return ret;
-	}
+    public Object visitAssign(Assign node) throws Exception {
+        Object ret = unhandled_node(node);
+        Type unrolledType = scope.unroll((Type) visit(node.getInternalValue()));
+        for (expr lhs : node.getInternalTargets()) {
+            ret = assign(lhs, unrolledType, node);
+        }
+
+        return ret;
+    }
 	
 	public Type assign(expr e, Type t, PythonTree node) throws Exception {
 		Type ret = (Type) unhandled_node(node);
 	
 	public Object visitNum(Num node) throws Exception {
 		//This will have to be updated whenever a new token is added to the parser
-		if(node.getAntlrType() == 91) {
-			node.data.internalType = GroundType.FLOAT;
-			return GroundType.FLOAT;
-		}
-		if(node.getAntlrType() == 92) {
-			node.data.internalType = GroundType.COMPLEX;
-			return GroundType.COMPLEX;
-		}
-		if(node.getAntlrType() == 90) {
-			node.data.internalType = GroundType.LONG;
-			return GroundType.LONG;
-		}
+	//	if(node.getAntlrType() == 91) {
+	//		node.data.internalType = GroundType.FLOAT;
+	//		return GroundType.FLOAT;
+	//	}
+	//	if(node.getAntlrType() == 92) {
+	//		node.data.internalType = GroundType.COMPLEX;
+	//		return GroundType.COMPLEX;
+//		}
+//		if(node.getAntlrType() == 90) {
+//			node.data.internalType = GroundType.LONG;
+//			return GroundType.LONG;
+//		}
 		
 //		try {
 //			node.getN().asInt();
 //			node.data.internalType = GroundType.JINT;
 //			return GroundType.JINT;
-//		} catch (Throwable t) {
-			node.data.internalType = GroundType.LONG;
-			return GroundType.LONG;
+////		} catch (Throwable t) {
+//			node.data.internalType = GroundType.LONG;
+//			return GroundType.LONG;
 //		}
+	node.data.internalType = DynamicType.Q;
+	return DynamicType.Q;
 	}
 	
 	public Object visitStr(Str node) throws Exception {
 		return r;
 	}
 	
-	public Object visitAttribute(Attribute node) throws Exception {
-		Type t = (Type) visit(node.getInternalValue());
-		if(t instanceof ArrayType) {
-			Type r = ((ArrayType) t).attributeType(node.getInternalAttr());
-			node.data.internalType = r;
-			return r;
-		}
-		node.data.internalType = DynamicType.Q;
-		return DynamicType.Q;
-	}
+    public Object visitAttribute(Attribute node) throws Exception {
+        Type t = (Type) visit(node.getInternalValue());
+        if (t instanceof ArrayType) {
+            Type r = ((ArrayType) t).attributeType(node.getInternalAttr());
+            node.data.internalType = r;
+            return r;
+        }
+        if (t instanceof ObjectType) {
+            Type r = ((ObjectType) t).attributeType(node.getInternalAttr());
+            node.data.internalType = r;
+            return r;
+        }
+        node.data.internalType = DynamicType.Q;
+        return DynamicType.Q;
+    }
 	
 	public Type matchBinop(operatorType op) throws Exception {
 		switch (op) {

File src/org/python/compiler/typechecker/UnitType.java

 package org.python.compiler.typechecker;
 
 public class UnitType extends Type {
-	public static UnitType Obtain(Type t, Scope scope) throws TypeError {
-		if(t instanceof UnitType)
-			return (UnitType) t;
-		if(t instanceof TypeAlias && t.instance(scope) == Types.UNIT)
-			return (UnitType) scope.lookupAlias((TypeAlias) t);
-		throw new TypecheckingError();
-	}
-	
-	public static UnitType UNIT = new UnitType();
-	
-	public Types instance(Scope scope) throws TypeError {
-		return Types.UNIT;
-	}
+    public static UnitType Obtain(Type t, Scope scope) throws TypeError {
+        if (t instanceof UnitType)
+            return (UnitType) t;
+        if (t instanceof TypeAlias && t.instance(scope) == Types.UNIT)
+            return (UnitType) scope.lookupAlias((TypeAlias) t);
+        throw new TypecheckingError();
+    }
 
-	public Type restrict(Type t, Scope scope) {
-		if(t instanceof DynamicType)
-			return DynamicType.Q;
-		return this;
-	}
+    public static UnitType UNIT = new UnitType();
 
-	public boolean subtype(Type t, Scope scope) {
-		if(t instanceof TypeAlias)
-			throw new TypecheckingError();
-		return t instanceof UnitType;
-	}
-	
-	public String toString() {
-		return "unit";
-	}
-	
-	public boolean equals(Object t) {
-		return t == this;
-	}
+    public Types instance(Scope scope) throws TypeError {
+        return Types.UNIT;
+    }
+
+    public Type restrict(Type t, Scope scope) {
+        if (t instanceof DynamicType)
+            return DynamicType.Q;
+        return this;
+    }
+
+    @Override
+    public Type merge(Type that) {
+        return super.merge(that);
+    }
+
+    public boolean subtype(Type t, Scope scope) {
+        if (t instanceof TypeAlias)
+            throw new TypecheckingError();
+        return t instanceof UnitType;
+    }
+
+    public String toString() {
+        return "unit";
+    }
+
+    public boolean equals(Object t) {
+        return t == this;
+    }
 }