2004/01/03 04:27:27
[org.ibex.core.git] / src / org / xwt / js / JSScope.java
index 8327ea1..3e797f3 100644 (file)
@@ -5,74 +5,87 @@ import org.xwt.util.*;
 import java.io.*;
 import java.util.*;
 
-/** Implementation of a JavaScript JSScope */
-public class JSScope extends JSCallable { 
-    private JSScope parentJSScope;
+/** Implementation of a JavaScript Scope */
+public class JSScope extends JS { 
+
+    private JSScope parentScope;
+
     private static final Object NULL_PLACEHOLDER = new Object();
-    public JSScope(JSScope parentJSScope) {
-        if (parentJSScope == this) throw new Error("can't make a scope its own parent!");
-        this.parentJSScope = parentJSScope;
-    }
 
-    public boolean isTransparent() { return false; }
-    public void declare(String s) { super.put(s, NULL_PLACEHOLDER); }
-    public JSScope getParentJSScope() { return parentJSScope; }
-    public boolean has(Object key) { return super.get(key) != null; }
+    public JSScope(JSScope parentScope) { this.parentScope = parentScope; }
+    public void declare(String s) throws JSExn { super.put(s, NULL_PLACEHOLDER); }
+    public JSScope getParentScope() { return parentScope; }
 
-    public Object get(Object key) {
+    public Object get(Object key) throws JSExn {
         Object o = super.get(key);
         if (o != null) return o == NULL_PLACEHOLDER ? null : o;
-        else return parentJSScope == null ? null : parentJSScope.get(key);
+        else return parentScope == null ? null : parentScope.get(key);
     }
 
-    public void put(Object key, Object val) {
-        if (parentJSScope != null && !has(key)) parentJSScope.put(key, val);
+    public boolean has(Object key) throws JSExn { return super.get(key) != null; }
+    public void put(Object key, Object val) throws JSExn {
+        if (parentScope != null && !has(key)) parentScope.put(key, val);
         else super.put(key, val == null ? NULL_PLACEHOLDER : val);
     }
 
     public static class Global extends JSScope {
         private final static Double NaN = new Double(Double.NaN);
         private final static Double POSITIVE_INFINITY = new Double(Double.POSITIVE_INFINITY);
-    
-        public Global(JSScope parent) {
-            super(parent);
-        }
-        public Object get(Object key) {
-            if(key.equals("NaN")) return NaN;
-            if(key.equals("Infinity")) return POSITIVE_INFINITY;
-            if(key.equals("undefined")) return null;
-            return super.get(key);
-        }
-
-        public Object call(Object method, JSArray args) {
-            if (method.equals("stringFromCharCode")) return stringFromCharCode(args);
-            else throw new JS.Exn("method not found");
-        }
 
-        public Object call1(Object method, Object arg0) {
-            //#switch(method)
-            case "parseInt": return parseInt(arg0, N(0));
-            case "isNaN": { double d = toDouble(arg0); return d == d ? F : T; }
-            case "isFinite": { double d = toDouble(arg0); return (d == d && !Double.isInfinite(d)) ? T : F; }
-            case "decodeURI": throw new JS.Exn("unimplemented");
-            case "decodeURIComponent": throw new JS.Exn("unimplemented");
-            case "encodeURI": throw new JS.Exn("unimplemented");
-            case "encodeURIComponent": throw new JS.Exn("unimplemented");
-            case "escape": throw new JS.Exn("unimplemented");
-            case "unescape": throw new JS.Exn("unimplemented");
+        public Global() { super(null); }
+        public Object get(Object key) throws JSExn {
+            //#switch(key)
+            case "NaN": return NaN;
+            case "Infinity": return POSITIVE_INFINITY;
+            case "undefined": return null;
+            case "stringFromCharCode": return METHOD;
+            case "parseInt": return METHOD;
+            case "isNaN": return METHOD;
+            case "isFinite": return METHOD;
+            case "decodeURI": return METHOD;
+            case "decodeURIComponent": return METHOD;
+            case "encodeURI": return METHOD;
+            case "encodeURIComponent": return METHOD;
+            case "escape": return METHOD;
+            case "unescape": return METHOD;
+            case "parseInt": return METHOD;
             //#end
-            return null;
-        }
-
-        public Object call2(Object method, Object arg1, Object arg2) {
-            if (method.equals("parseInt")) return parseInt(arg1, arg2);
-            return null;
+            return super.get(key);
         }
 
-        private Object stringFromCharCode(JSArray args) {
-            char buf[] = new char[args.length()];
-            for(int i=0;i<args.length();i++) buf[i] = (char)(JS.toInt(args.elementAt(i)) & 0xffff);
-            return new String(buf);
+        public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+            switch(nargs) {
+                case 0: {
+                    //#switch(method)
+                    case "stringFromCharCode":
+                        char buf[] = new char[nargs];
+                        for(int i=0; i<nargs; i++) buf[i] = (char)(JS.toInt(i==0?a0:i==1?a1:i==2?a2:rest[i-3]) & 0xffff);
+                        return new String(buf);
+                    //#end
+                    break;
+                }
+                case 1: {
+                    //#switch(method)
+                    case "parseInt": return parseInt(a0, N(0));
+                    case "isNaN": { double d = toDouble(a0); return d == d ? F : T; }
+                    case "isFinite": { double d = toDouble(a0); return (d == d && !Double.isInfinite(d)) ? T : F; }
+                    case "decodeURI": throw new JSExn("unimplemented");
+                    case "decodeURIComponent": throw new JSExn("unimplemented");
+                    case "encodeURI": throw new JSExn("unimplemented");
+                    case "encodeURIComponent": throw new JSExn("unimplemented");
+                    case "escape": throw new JSExn("unimplemented");
+                    case "unescape": throw new JSExn("unimplemented");
+                    //#end
+                    break;
+                }
+                case 2: {
+                    //#switch(method)
+                    case "parseInt": return parseInt(a0, a1);
+                    //#end
+                    break;
+                }
+            }
+            return super.callMethod(method, a0, a1, a2, rest, nargs);
         }
 
         private Object parseInt(Object arg, Object r) {
@@ -95,7 +108,7 @@ public class JSScope extends JSCallable {
                     radix = 16;
                 } else {
                     radix = 8;
-                    if(length == start || Character.digit(s.charAt(start+1),8)==-1) return new Integer(0);
+                    if(length == start || Character.digit(s.charAt(start+1),8)==-1) return JS.ZERO;
                 }
             }
             if(radix == 0) radix = 10;
@@ -103,7 +116,7 @@ public class JSScope extends JSCallable {
             // try the fast way first
             try {
                 String s2 = start == 0 ? s : s.substring(start);
-                return new Integer(sign*Integer.parseInt(s2,radix));
+                return JS.N(sign*Integer.parseInt(s2,radix));
             } catch(NumberFormatException e) { }
             // fall through to a slower but emca-compliant method
             for(int i=start;i<length;i++) {
@@ -112,8 +125,8 @@ public class JSScope extends JSCallable {
                 n = n*radix + digit;
                 if(n < 0) return NaN; // overflow;
             }
-            if(n <= Integer.MAX_VALUE) return new Integer(sign*(int)n);
-            return new Long((long)sign*n);
+            if(n <= Integer.MAX_VALUE) return JS.N(sign*(int)n);
+            return JS.N((long)sign*n);
         }
 
         private Object parseFloat(Object arg) {
@@ -126,7 +139,7 @@ public class JSScope extends JSCallable {
             // trailing garbage
             while(start < end) {
                 try {
-                    return new Double(s.substring(start,length));
+                    return JS.N(s.substring(start,length));
                 } catch(NumberFormatException e) { }
                 end--;
             }