cloneable is an interface
[org.ibex.core.git] / src / org / ibex / js / JS.java
index 378e125..0290e46 100644 (file)
@@ -2,37 +2,40 @@
 package org.ibex.js; 
 
 import org.ibex.util.*; 
-import org.ibex.*; 
 import java.io.*;
 import java.util.*;
 
 /** The minimum set of functionality required for objects which are manipulated by JavaScript */
 public class JS extends org.ibex.util.BalancedTree { 
 
-    public static final Object METHOD = new Object();
+    public static boolean checkAssertions = false;
+
+    public static final Object METHOD = new Object() { public String toString() { return "JS.METHOD"; } };
     public final JS unclone() { return _unclone(); }
+    public final JS jsclone() throws JSExn { return new Clone(this); }
     public Enumeration keys() throws JSExn { return entries == null ? emptyEnumeration : entries.keys(); }
     public Object get(Object key) throws JSExn { return entries == null ? null : entries.get(key, null); }
     public void put(Object key, Object val) throws JSExn { (entries==null?entries=new Hash():entries).put(key,null,val); }
     public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
-        throw new JSExn("attempted to call the null value (method "+method+")");
+        throw new JSExn("you cannot call this object (class=" + this.getClass().getName() +")");
     }    
+    // FIXME: JSArgs objects, pointers into stack frame
     public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
         throw new JSExn("you cannot call this object (class=" + this.getClass().getName() +")");
     }
 
     JS _unclone() { return this; }
-    public static class Cloneable extends JS {
-        public Object jsclone() throws JSExn {
-            return new Clone(this);
-        }
-    }
-
-    public static class Clone extends JS.Cloneable {
-        protected JS.Cloneable clonee = null;
+    
+    public interface Cloneable { }
+    
+    public static class Clone extends JS implements Cloneable {
+        protected JS clonee;
         JS _unclone() { return clonee.unclone(); }
-        public JS.Cloneable getClonee() { return clonee; }
-        public Clone(JS.Cloneable clonee) { this.clonee = clonee; }
+        public JS getClonee() { return clonee; }
+        public Clone(JS clonee) throws JSExn {
+            if(!(clonee instanceof Cloneable)) throw new JSExn("this object isn't cloneable");
+            this.clonee = clonee;
+        }
         public boolean equals(Object o) {
             if (!(o instanceof JS)) return false;
             return unclone() == ((JS)o).unclone();
@@ -67,7 +70,7 @@ public class JS extends org.ibex.util.BalancedTree {
         return new JS.UnpauseCallback(i);
     }
 
-    public static class UnpauseCallback implements Scheduler.Task {
+    public static class UnpauseCallback implements Task {
         Interpreter i;
         UnpauseCallback(Interpreter i) { this.i = i; }
         public void perform() throws JSExn { unpause(null); }
@@ -130,7 +133,12 @@ public class JS extends org.ibex.util.BalancedTree {
             if((int)d == d) return Integer.toString((int)d);
             return o.toString();
         }
-        throw new RuntimeException("can't coerce "+o+" [" + o.getClass().getName() + "]");
+        if (o instanceof JS) return ((JS)o).coerceToString();   // HACK for now, this will probably go away
+        throw new RuntimeException("can't coerce "+o+" [" + o.getClass().getName() + "] to type String.");
+    }
+
+    public String coerceToString() {
+        throw new RuntimeException("can't coerce "+this+" [" + getClass().getName() + "] to type String.");
     }
 
     // Instance Methods ////////////////////////////////////////////////////////////////////