Object ret = null;
if (o == null) throw je("tried to get property \"" + v + "\" from the null value");
if (v == null) throw je("tried to get the null key from " + o);
- if (o instanceof String) {
- ret = getFromString((String)o, v);
- } else if (o instanceof Boolean) {
- throw je("Not Implemented: properties on Boolean objects");
- } else if (o instanceof Number) {
- Log.log(this, "Not Implemented: properties on Number objects");
- } else if (o instanceof JS) {
+ if (o instanceof String || o instanceof Number || o instanceof Boolean)
+ ret = Internal.getFromPrimitive(o,v);
+ else if (o instanceof JS)
ret = ((JS)o).get(v);
- }
+ else
+ throw je("tried to get property " + v + " from a " + o.getClass().getName());
t.push(ret);
break;
}
-
- case CALL: {
+
+ case CALLMETHOD:
+ case CALL:
+ {
JS.Array arguments = new JS.Array();
int numArgs = JS.toNumber(arg[pc]).intValue();
arguments.setSize(numArgs);
for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(t.pop(), j);
- JS.Callable f = (JS.Callable)t.pop();
- if (f == null) throw je("attempted to call null");
+ Object o = t.pop();
+ if(o == null) throw je("attempted to call null");
try {
- t.push(f.call(arguments));
+ Object ret;
+ if(op[pc] == CALLMETHOD) {
+ Object method = o;
+ o = t.pop();
+ if(o instanceof String || o instanceof Number || o instanceof Boolean)
+ ret = Internal.callMethodOnPrimitive(o,method,arguments);
+ else if(o instanceof JS)
+ ret = ((JS)o).callMethod(method,arguments,false);
+ else
+ throw new JS.Exn("Tried to call a method on an object that isn't a JS object");
+ } else {
+ ret = ((JS.Callable)o).call(arguments);
+ }
+ t.push(ret);
break;
} catch (JS.Exn e) {
t.push(e);
return sb.toString();
}
- // Helpers for Number, String, and Boolean ////////////////////////////////////////
-
- private static Object getFromString(final String o, final Object v) {
- if (v.equals("length")) return new Integer(((String)o).length());
- else if (v.equals("substring")) return new JS.Callable() {
- public Object call(JS.Array args) {
- if (args.length() == 1) return ((String)o).substring(JS.toNumber(args.elementAt(0)).intValue());
- else if (args.length() == 2) return ((String)o).substring(JS.toNumber(args.elementAt(0)).intValue(),
- JS.toNumber(args.elementAt(1)).intValue());
- else throw new JS.Exn("String.substring() can only take one or two arguments");
- }
- };
- else if (v.equals("toLowerCase")) return new JS.Callable() {
- public Object call(JS.Array args) {
- return ((String)o).toLowerCase();
- } };
- else if (v.equals("toUpperCase")) return new JS.Callable() {
- public Object call(JS.Array args) {
- return ((String)o).toString().toUpperCase();
- } };
- else if (v.equals("charAt")) return new JS.Callable() {
- public Object call(JS.Array args) {
- return ((String)o).charAt(JS.toNumber(args.elementAt(0)).intValue()) + "";
- } };
- else if (v.equals("lastIndexOf")) return new JS.Callable() {
- public Object call(JS.Array args) {
- if (args.length() != 1) return null;
- return new Integer(((String)o).lastIndexOf(args.elementAt(0).toString()));
- } };
- else if (v.equals("indexOf")) return new JS.Callable() {
- public Object call(JS.Array args) {
- if (args.length() != 1) return null;
- return new Integer(((String)o).indexOf(args.elementAt(0).toString()));
- } };
- else if(v.equals("match")) return new JS.Callable() {
- public Object call(JS.Array args) {
- return Regexp.stringMatch(o,args);
- } };
- else if(v.equals("search")) return new JS.Callable() {
- public Object call(JS.Array args) {
- return Regexp.stringSearch(o,args);
- } };
- else if(v.equals("replace")) return new JS.Callable() {
- public Object call(JS.Array args) {
- return Regexp.stringReplace(o,args);
- } };
- else if(v.equals("split")) return new JS.Callable() {
- public Object call(JS.Array args) {
- return Regexp.stringSplit(o,args);
- } };
-
-
- throw new JS.Exn("Not Implemented: propery " + v + " on String objects");
- }
-
-
// Exception Stuff ////////////////////////////////////////////////////////////////
static class EvaluatorException extends RuntimeException { public EvaluatorException(String s) { super(s); } }