You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xap-commits@incubator.apache.org by mt...@apache.org on 2006/08/16 21:57:12 UTC

svn commit: r432045 [2/6] - in /incubator/xap/trunk/buildscripts: ./ doctool/ doctool/narcissus/ doctool/narcissus/CVS/ lib/ profiles/

Added: incubator/xap/trunk/buildscripts/doctool/narcissus/jsexec.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/buildscripts/doctool/narcissus/jsexec.js?rev=432045&view=auto
==============================================================================
--- incubator/xap/trunk/buildscripts/doctool/narcissus/jsexec.js (added)
+++ incubator/xap/trunk/buildscripts/doctool/narcissus/jsexec.js Wed Aug 16 14:57:09 2006
@@ -0,0 +1,957 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * vim: set ts=4 sw=4 et tw=80:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Narcissus JavaScript engine.
+ *
+ * The Initial Developer of the Original Code is
+ * Brendan Eich <br...@mozilla.org>.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Narcissus - JS implemented in JS.
+ *
+ * Execution of parse trees.
+ *
+ * Standard classes except for eval, Function, Array, and String are borrowed
+ * from the host JS environment.  Function is metacircular.  Array and String
+ * are reflected via wrapping the corresponding native constructor and adding
+ * an extra level of prototype-based delegation.
+ */
+
+const GLOBAL_CODE = 0, EVAL_CODE = 1, FUNCTION_CODE = 2;
+
+function ExecutionContext(type) {
+    this.type = type;
+}
+
+var global = {
+    // Value properties.
+    NaN: NaN, Infinity: Infinity, undefined: undefined,
+
+    // Function properties.
+    eval: function eval(s) {
+        if (typeof s != "string")
+            return s;
+
+        var x = ExecutionContext.current;
+        var x2 = new ExecutionContext(EVAL_CODE);
+        x2.thisObject = x.thisObject;
+        x2.caller = x.caller;
+        x2.callee = x.callee;
+        x2.scope = x.scope;
+        ExecutionContext.current = x2;
+        try {
+            execute(parse(s), x2);
+        } catch (e if e == THROW) {
+            x.result = x2.result;
+            throw e;
+        } finally {
+            ExecutionContext.current = x;
+        }
+        return x2.result;
+    },
+    parseInt: parseInt, parseFloat: parseFloat,
+    isNaN: isNaN, isFinite: isFinite,
+    decodeURI: decodeURI, encodeURI: encodeURI,
+    decodeURIComponent: decodeURIComponent,
+    encodeURIComponent: encodeURIComponent,
+
+    // Class constructors.  Where ECMA-262 requires C.length == 1, we declare
+    // a dummy formal parameter.
+    Object: Object,
+    Function: function Function(dummy) {
+        var p = "", b = "", n = arguments.length;
+        if (n) {
+            var m = n - 1;
+            if (m) {
+                p += arguments[0];
+                for (var k = 1; k < m; k++)
+                    p += "," + arguments[k];
+            }
+            b += arguments[m];
+        }
+
+        // XXX We want to pass a good file and line to the tokenizer.
+        // Note the anonymous name to maintain parity with Spidermonkey.
+        var t = new Tokenizer("anonymous(" + p + ") {" + b + "}");
+
+        // NB: Use the STATEMENT_FORM constant since we don't want to push this
+        // function onto the null compilation context.
+        var f = FunctionDefinition(t, null, false, STATEMENT_FORM);
+        var s = {object: global, parent: null};
+        return new FunctionObject(f, s);
+    },
+    Array: function Array(dummy) {
+        // Array when called as a function acts as a constructor.
+        return GLOBAL.Array.apply(this, arguments);
+    },
+    String: function String(s) {
+        // Called as function or constructor: convert argument to string type.
+        s = arguments.length ? "" + s : "";
+        if (this instanceof String) {
+            // Called as constructor: save the argument as the string value
+            // of this String object and return this object.
+            this.value = s;
+            return this;
+        }
+        return s;
+    },
+    Boolean: Boolean, Number: Number, Date: Date, RegExp: RegExp,
+    Error: Error, EvalError: EvalError, RangeError: RangeError,
+    ReferenceError: ReferenceError, SyntaxError: SyntaxError,
+    TypeError: TypeError, URIError: URIError,
+
+    // Other properties.
+    Math: Math,
+
+    // Extensions to ECMA.
+    snarf: snarf, evaluate: evaluate,
+    load: function load(s) {
+        if (typeof s != "string")
+            return s;
+
+        evaluate(snarf(s), s, 1)
+    },
+    print: print, version: null
+};
+
+// Helper to avoid Object.prototype.hasOwnProperty polluting scope objects.
+function hasDirectProperty(o, p) {
+    return Object.prototype.hasOwnProperty.call(o, p);
+}
+
+// Reflect a host class into the target global environment by delegation.
+function reflectClass(name, proto) {
+    var gctor = global[name];
+    gctor.__defineProperty__('prototype', proto, true, true, true);
+    proto.__defineProperty__('constructor', gctor, false, false, true);
+    return proto;
+}
+
+// Reflect Array -- note that all Array methods are generic.
+reflectClass('Array', new Array);
+
+// Reflect String, overriding non-generic methods.
+var gSp = reflectClass('String', new String);
+gSp.toSource = function () { return this.value.toSource(); };
+gSp.toString = function () { return this.value; };
+gSp.valueOf  = function () { return this.value; };
+global.String.fromCharCode = String.fromCharCode;
+
+var XCp = ExecutionContext.prototype;
+ExecutionContext.current = XCp.caller = XCp.callee = null;
+XCp.scope = {object: global, parent: null};
+XCp.thisObject = global;
+XCp.result = undefined;
+XCp.target = null;
+
+function Reference(base, propertyName, node) {
+    this.base = base;
+    this.propertyName = propertyName;
+    this.node = node;
+}
+
+Reference.prototype.toString = function () { return this.node.getSource(); }
+
+function getValue(v) {
+    if (v instanceof Reference) {
+        if (!v.base) {
+            throw new ReferenceError(v.propertyName + " is not defined",
+                                     v.node.filename, v.node.lineno);
+        }
+        return v.base[v.propertyName];
+    }
+    return v;
+}
+
+function putValue(v, w, vn) {
+    if (v instanceof Reference)
+        return (v.base || global)[v.propertyName] = w;
+    throw new ReferenceError("Invalid assignment left-hand side",
+                             vn.filename, vn.lineno);
+}
+
+function isPrimitive(v) {
+    var t = typeof v;
+    return (t == "object") ? v === null : t != "function";
+}
+
+function isObject(v) {
+    var t = typeof v;
+    return (t == "object") ? v !== null : t == "function";
+}
+
+// If r instanceof Reference, v == getValue(r); else v === r.  If passed, rn
+// is the node whose execute result was r.
+function toObject(v, r, rn) {
+    switch (typeof v) {
+      case "boolean":
+        return new Boolean(v);
+      case "number":
+        return new Number(v);
+      case "string":
+        return new String(v);
+      case "function":
+        return v;
+      case "object":
+        if (v !== null)
+            return v;
+    }
+    var message = r + " (type " + (typeof v) + ") has no properties";
+    throw rn ? new TypeError(message, rn.filename, rn.lineno)
+             : new TypeError(message);
+}
+
+function execute(n, x) {
+    var a, f, i, j, r, s, t, u, v;
+
+    switch (n.type) {
+      case FUNCTION:
+        if (n.functionForm != DECLARED_FORM) {
+            if (!n.name || n.functionForm == STATEMENT_FORM) {
+                v = new FunctionObject(n, x.scope);
+                if (n.functionForm == STATEMENT_FORM)
+                    x.scope.object.__defineProperty__(n.name, v, true);
+            } else {
+                t = new Object;
+                x.scope = {object: t, parent: x.scope};
+                try {
+                    v = new FunctionObject(n, x.scope);
+                    t.__defineProperty__(n.name, v, true, true);
+                } finally {
+                    x.scope = x.scope.parent;
+                }
+            }
+        }
+        break;
+
+      case SCRIPT:
+        t = x.scope.object;
+        a = n.funDecls;
+        for (i = 0, j = a.length; i < j; i++) {
+            s = a[i].name;
+            f = new FunctionObject(a[i], x.scope);
+            t.__defineProperty__(s, f, x.type != EVAL_CODE);
+        }
+        a = n.varDecls;
+        for (i = 0, j = a.length; i < j; i++) {
+            u = a[i];
+            s = u.name;
+            if (u.readOnly && hasDirectProperty(t, s)) {
+                throw new TypeError("Redeclaration of const " + s,
+                                    u.filename, u.lineno);
+            }
+            if (u.readOnly || !hasDirectProperty(t, s)) {
+                t.__defineProperty__(s, undefined, x.type != EVAL_CODE,
+                                     u.readOnly);
+            }
+        }
+        // FALL THROUGH
+
+      case BLOCK:
+        for (i = 0, j = n.length; i < j; i++)
+            execute(n[i], x);
+        break;
+
+      case IF:
+        if (getValue(execute(n.condition, x)))
+            execute(n.thenPart, x);
+        else if (n.elsePart)
+            execute(n.elsePart, x);
+        break;
+
+      case SWITCH:
+        s = getValue(execute(n.discriminant, x));
+        a = n.cases;
+        var matchDefault = false;
+      switch_loop:
+        for (i = 0, j = a.length; ; i++) {
+            if (i == j) {
+                if (n.defaultIndex >= 0) {
+                    i = n.defaultIndex - 1; // no case matched, do default
+                    matchDefault = true;
+                    continue;
+                }
+                break;                      // no default, exit switch_loop
+            }
+            t = a[i];                       // next case (might be default!)
+            if (t.type == CASE) {
+                u = getValue(execute(t.caseLabel, x));
+            } else {
+                if (!matchDefault)          // not defaulting, skip for now
+                    continue;
+                u = s;                      // force match to do default
+            }
+            if (u === s) {
+                for (;;) {                  // this loop exits switch_loop
+                    if (t.statements.length) {
+                        try {
+                            execute(t.statements, x);
+                        } catch (e if e == BREAK && x.target == n) {
+                            break switch_loop;
+                        }
+                    }
+                    if (++i == j)
+                        break switch_loop;
+                    t = a[i];
+                }
+                // NOT REACHED
+            }
+        }
+        break;
+
+      case FOR:
+        n.setup && getValue(execute(n.setup, x));
+        // FALL THROUGH
+      case WHILE:
+        while (!n.condition || getValue(execute(n.condition, x))) {
+            try {
+                execute(n.body, x);
+            } catch (e if e == BREAK && x.target == n) {
+                break;
+            } catch (e if e == CONTINUE && x.target == n) {
+                continue;
+            }
+            n.update && getValue(execute(n.update, x));
+        }
+        break;
+
+      case FOR_IN:
+        u = n.varDecl;
+        if (u)
+            execute(u, x);
+        r = n.iterator;
+        s = execute(n.object, x);
+        t = toObject(getValue(s), s, n.object);
+        a = [];
+        for (i in t)
+            a.push(i);
+        for (i = 0, j = a.length; i < j; i++) {
+            putValue(execute(r, x), a[i], r);
+            try {
+                execute(n.body, x);
+            } catch (e if e == BREAK && x.target == n) {
+                break;
+            } catch (e if e == CONTINUE && x.target == n) {
+                continue;
+            }
+        }
+        break;
+
+      case DO:
+        do {
+            try {
+                execute(n.body, x);
+            } catch (e if e == BREAK && x.target == n) {
+                break;
+            } catch (e if e == CONTINUE && x.target == n) {
+                continue;
+            }
+        } while (getValue(execute(n.condition, x)));
+        break;
+
+      case BREAK:
+      case CONTINUE:
+        x.target = n.target;
+        throw n.type;
+
+      case TRY:
+        try {
+            execute(n.tryBlock, x);
+        } catch (e if e == THROW && (j = n.catchClauses.length)) {
+            e = x.result;
+            x.result = undefined;
+            for (i = 0; ; i++) {
+                if (i == j) {
+                    x.result = e;
+                    throw THROW;
+                }
+                t = n.catchClauses[i];
+                x.scope = {object: {}, parent: x.scope};
+                x.scope.object.__defineProperty__(t.varName, e, true);
+                try {
+                    if (t.guard && !getValue(execute(t.guard, x)))
+                        continue;
+                    execute(t.block, x);
+                    break;
+                } finally {
+                    x.scope = x.scope.parent;
+                }
+            }
+        } finally {
+            if (n.finallyBlock)
+                execute(n.finallyBlock, x);
+        }
+        break;
+
+      case THROW:
+        x.result = getValue(execute(n.exception, x));
+        throw THROW;
+
+      case RETURN:
+        x.result = getValue(execute(n.value, x));
+        throw RETURN;
+
+      case WITH:
+        r = execute(n.object, x);
+        t = toObject(getValue(r), r, n.object);
+        x.scope = {object: t, parent: x.scope};
+        try {
+            execute(n.body, x);
+        } finally {
+            x.scope = x.scope.parent;
+        }
+        break;
+
+      case VAR:
+      case CONST:
+        for (i = 0, j = n.length; i < j; i++) {
+            u = n[i].initializer;
+            if (!u)
+                continue;
+            t = n[i].name;
+            for (s = x.scope; s; s = s.parent) {
+                if (hasDirectProperty(s.object, t))
+                    break;
+            }
+            u = getValue(execute(u, x));
+            if (n.type == CONST)
+                s.object.__defineProperty__(t, u, x.type != EVAL_CODE, true);
+            else
+                s.object[t] = u;
+        }
+        break;
+
+      case DEBUGGER:
+        throw "NYI: " + tokens[n.type];
+
+      case SEMICOLON:
+        if (n.expression)
+            x.result = getValue(execute(n.expression, x));
+        break;
+
+      case LABEL:
+        try {
+            execute(n.statement, x);
+        } catch (e if e == BREAK && x.target == n) {
+        }
+        break;
+
+      case COMMA:
+        for (i = 0, j = n.length; i < j; i++)
+            v = getValue(execute(n[i], x));
+        break;
+
+      case ASSIGN:
+        r = execute(n[0], x);
+        t = n[0].assignOp;
+        if (t)
+            u = getValue(r);
+        v = getValue(execute(n[1], x));
+        if (t) {
+            switch (t) {
+              case BITWISE_OR:  v = u | v; break;
+              case BITWISE_XOR: v = u ^ v; break;
+              case BITWISE_AND: v = u & v; break;
+              case LSH:         v = u << v; break;
+              case RSH:         v = u >> v; break;
+              case URSH:        v = u >>> v; break;
+              case PLUS:        v = u + v; break;
+              case MINUS:       v = u - v; break;
+              case MUL:         v = u * v; break;
+              case DIV:         v = u / v; break;
+              case MOD:         v = u % v; break;
+            }
+        }
+        putValue(r, v, n[0]);
+        break;
+
+      case CONDITIONAL:
+        v = getValue(execute(n[0], x)) ? getValue(execute(n[1], x))
+                                       : getValue(execute(n[2], x));
+        break;
+
+      case OR:
+        v = getValue(execute(n[0], x)) || getValue(execute(n[1], x));
+        break;
+
+      case AND:
+        v = getValue(execute(n[0], x)) && getValue(execute(n[1], x));
+        break;
+
+      case BITWISE_OR:
+        v = getValue(execute(n[0], x)) | getValue(execute(n[1], x));
+        break;
+
+      case BITWISE_XOR:
+        v = getValue(execute(n[0], x)) ^ getValue(execute(n[1], x));
+        break;
+
+      case BITWISE_AND:
+        v = getValue(execute(n[0], x)) & getValue(execute(n[1], x));
+        break;
+
+      case EQ:
+        v = getValue(execute(n[0], x)) == getValue(execute(n[1], x));
+        break;
+
+      case NE:
+        v = getValue(execute(n[0], x)) != getValue(execute(n[1], x));
+        break;
+
+      case STRICT_EQ:
+        v = getValue(execute(n[0], x)) === getValue(execute(n[1], x));
+        break;
+
+      case STRICT_NE:
+        v = getValue(execute(n[0], x)) !== getValue(execute(n[1], x));
+        break;
+
+      case LT:
+        v = getValue(execute(n[0], x)) < getValue(execute(n[1], x));
+        break;
+
+      case LE:
+        v = getValue(execute(n[0], x)) <= getValue(execute(n[1], x));
+        break;
+
+      case GE:
+        v = getValue(execute(n[0], x)) >= getValue(execute(n[1], x));
+        break;
+
+      case GT:
+        v = getValue(execute(n[0], x)) > getValue(execute(n[1], x));
+        break;
+
+      case IN:
+        v = getValue(execute(n[0], x)) in getValue(execute(n[1], x));
+        break;
+
+      case INSTANCEOF:
+        t = getValue(execute(n[0], x));
+        u = getValue(execute(n[1], x));
+        if (isObject(u) && typeof u.__hasInstance__ == "function")
+            v = u.__hasInstance__(t);
+        else
+            v = t instanceof u;
+        break;
+
+      case LSH:
+        v = getValue(execute(n[0], x)) << getValue(execute(n[1], x));
+        break;
+
+      case RSH:
+        v = getValue(execute(n[0], x)) >> getValue(execute(n[1], x));
+        break;
+
+      case URSH:
+        v = getValue(execute(n[0], x)) >>> getValue(execute(n[1], x));
+        break;
+
+      case PLUS:
+        v = getValue(execute(n[0], x)) + getValue(execute(n[1], x));
+        break;
+
+      case MINUS:
+        v = getValue(execute(n[0], x)) - getValue(execute(n[1], x));
+        break;
+
+      case MUL:
+        v = getValue(execute(n[0], x)) * getValue(execute(n[1], x));
+        break;
+
+      case DIV:
+        v = getValue(execute(n[0], x)) / getValue(execute(n[1], x));
+        break;
+
+      case MOD:
+        v = getValue(execute(n[0], x)) % getValue(execute(n[1], x));
+        break;
+
+      case DELETE:
+        t = execute(n[0], x);
+        v = !(t instanceof Reference) || delete t.base[t.propertyName];
+        break;
+
+      case VOID:
+        getValue(execute(n[0], x));
+        break;
+
+      case TYPEOF:
+        t = execute(n[0], x);
+        if (t instanceof Reference)
+            t = t.base ? t.base[t.propertyName] : undefined;
+        v = typeof t;
+        break;
+
+      case NOT:
+        v = !getValue(execute(n[0], x));
+        break;
+
+      case BITWISE_NOT:
+        v = ~getValue(execute(n[0], x));
+        break;
+
+      case UNARY_PLUS:
+        v = +getValue(execute(n[0], x));
+        break;
+
+      case UNARY_MINUS:
+        v = -getValue(execute(n[0], x));
+        break;
+
+      case INCREMENT:
+      case DECREMENT:
+        t = execute(n[0], x);
+        u = Number(getValue(t));
+        if (n.postfix)
+            v = u;
+        putValue(t, (n.type == INCREMENT) ? ++u : --u, n[0]);
+        if (!n.postfix)
+            v = u;
+        break;
+
+      case DOT:
+        r = execute(n[0], x);
+        t = getValue(r);
+        u = n[1].value;
+        v = new Reference(toObject(t, r, n[0]), u, n);
+        break;
+
+      case INDEX:
+        r = execute(n[0], x);
+        t = getValue(r);
+        u = getValue(execute(n[1], x));
+        v = new Reference(toObject(t, r, n[0]), String(u), n);
+        break;
+
+      case LIST:
+        // Curse ECMA for specifying that arguments is not an Array object!
+        v = {};
+        for (i = 0, j = n.length; i < j; i++) {
+            u = getValue(execute(n[i], x));
+            v.__defineProperty__(i, u, false, false, true);
+        }
+        v.__defineProperty__('length', i, false, false, true);
+        break;
+
+      case CALL:
+        r = execute(n[0], x);
+        a = execute(n[1], x);
+        f = getValue(r);
+        if (isPrimitive(f) || typeof f.__call__ != "function") {
+            throw new TypeError(r + " is not callable",
+                                n[0].filename, n[0].lineno);
+        }
+        t = (r instanceof Reference) ? r.base : null;
+        if (t instanceof Activation)
+            t = null;
+        v = f.__call__(t, a, x);
+        break;
+
+      case NEW:
+      case NEW_WITH_ARGS:
+        r = execute(n[0], x);
+        f = getValue(r);
+        if (n.type == NEW) {
+            a = {};
+            a.__defineProperty__('length', 0, false, false, true);
+        } else {
+            a = execute(n[1], x);
+        }
+        if (isPrimitive(f) || typeof f.__construct__ != "function") {
+            throw new TypeError(r + " is not a constructor",
+                                n[0].filename, n[0].lineno);
+        }
+        v = f.__construct__(a, x);
+        break;
+
+      case ARRAY_INIT:
+        v = [];
+        for (i = 0, j = n.length; i < j; i++) {
+            if (n[i])
+                v[i] = getValue(execute(n[i], x));
+        }
+        v.length = j;
+        break;
+
+      case OBJECT_INIT:
+        v = {};
+        for (i = 0, j = n.length; i < j; i++) {
+            t = n[i];
+            if (t.type == PROPERTY_INIT) {
+                v[t[0].value] = getValue(execute(t[1], x));
+            } else {
+                f = new FunctionObject(t, x.scope);
+                u = (t.type == GETTER) ? '__defineGetter__'
+                                       : '__defineSetter__';
+                v[u](t.name, thunk(f, x));
+            }
+        }
+        break;
+
+      case NULL:
+        v = null;
+        break;
+
+      case THIS:
+        v = x.thisObject;
+        break;
+
+      case TRUE:
+        v = true;
+        break;
+
+      case FALSE:
+        v = false;
+        break;
+
+      case IDENTIFIER:
+        for (s = x.scope; s; s = s.parent) {
+            if (n.value in s.object)
+                break;
+        }
+        v = new Reference(s && s.object, n.value, n);
+        break;
+
+      case NUMBER:
+      case STRING:
+      case REGEXP:
+        v = n.value;
+        break;
+
+      case GROUP:
+        v = execute(n[0], x);
+        break;
+
+      default:
+        throw "PANIC: unknown operation " + n.type + ": " + uneval(n);
+    }
+
+    return v;
+}
+
+function Activation(f, a) {
+    for (var i = 0, j = f.params.length; i < j; i++)
+        this.__defineProperty__(f.params[i], a[i], true);
+    this.__defineProperty__('arguments', a, true);
+}
+
+// Null Activation.prototype's proto slot so that Object.prototype.* does not
+// pollute the scope of heavyweight functions.  Also delete its 'constructor'
+// property so that it doesn't pollute function scopes.  But first, we must
+// copy __defineProperty__ down from Object.prototype.
+
+Activation.prototype.__defineProperty__ = Object.prototype.__defineProperty__;
+Activation.prototype.__proto__ = null;
+delete Activation.prototype.constructor;
+
+function FunctionObject(node, scope) {
+    this.node = node;
+    this.scope = scope;
+    this.__defineProperty__('length', node.params.length, true, true, true);
+    var proto = {};
+    this.__defineProperty__('prototype', proto, true);
+    proto.__defineProperty__('constructor', this, false, false, true);
+}
+
+var FOp = FunctionObject.prototype = {
+    // Internal methods.
+    __call__: function (t, a, x) {
+        var x2 = new ExecutionContext(FUNCTION_CODE);
+        x2.thisObject = t || global;
+        x2.caller = x;
+        x2.callee = this;
+        a.__defineProperty__('callee', this, false, false, true);
+        var f = this.node;
+        x2.scope = {object: new Activation(f, a), parent: this.scope};
+
+        ExecutionContext.current = x2;
+        try {
+            execute(f.body, x2);
+        } catch (e if e == RETURN) {
+            return x2.result;
+        } catch (e if e == THROW) {
+            x.result = x2.result;
+            throw THROW;
+        } finally {
+            ExecutionContext.current = x;
+        }
+        return undefined;
+    },
+
+    __construct__: function (a, x) {
+        var o = new Object;
+        var p = this.prototype;
+        if (isObject(p))
+            o.__proto__ = p;
+        // else o.__proto__ defaulted to Object.prototype
+
+        var v = this.__call__(o, a, x);
+        if (isObject(v))
+            return v;
+        return o;
+    },
+
+    __hasInstance__: function (v) {
+        if (isPrimitive(v))
+            return false;
+        var p = this.prototype;
+        if (isPrimitive(p)) {
+            throw new TypeError("'prototype' property is not an object",
+                                this.node.filename, this.node.lineno);
+        }
+        var o;
+        while ((o = v.__proto__)) {
+            if (o == p)
+                return true;
+            v = o;
+        }
+        return false;
+    },
+
+    // Standard methods.
+    toString: function () {
+        return this.node.getSource();
+    },
+
+    apply: function (t, a) {
+        // Curse ECMA again!
+        if (typeof this.__call__ != "function") {
+            throw new TypeError("Function.prototype.apply called on" +
+                                " uncallable object");
+        }
+
+        if (t === undefined || t === null)
+            t = global;
+        else if (typeof t != "object")
+            t = toObject(t, t);
+
+        if (a === undefined || a === null) {
+            a = {};
+            a.__defineProperty__('length', 0, false, false, true);
+        } else if (a instanceof Array) {
+            var v = {};
+            for (var i = 0, j = a.length; i < j; i++)
+                v.__defineProperty__(i, a[i], false, false, true);
+            v.__defineProperty__('length', i, false, false, true);
+            a = v;
+        } else if (!(a instanceof Object)) {
+            // XXX check for a non-arguments object
+            throw new TypeError("Second argument to Function.prototype.apply" +
+                                " must be an array or arguments object",
+                                this.node.filename, this.node.lineno);
+        }
+
+        return this.__call__(t, a, ExecutionContext.current);
+    },
+
+    call: function (t) {
+        // Curse ECMA a third time!
+        var a = Array.prototype.splice.call(arguments, 1);
+        return this.apply(t, a);
+    }
+};
+
+// Connect Function.prototype and Function.prototype.constructor in global.
+reflectClass('Function', FOp);
+
+// Help native and host-scripted functions be like FunctionObjects.
+var Fp = Function.prototype;
+var REp = RegExp.prototype;
+
+if (!('__call__' in Fp)) {
+    Fp.__defineProperty__('__call__', function (t, a, x) {
+        // Curse ECMA yet again!
+        a = Array.prototype.splice.call(a, 0, a.length);
+        return this.apply(t, a);
+    }, true, true, true);
+
+    REp.__defineProperty__('__call__', function (t, a, x) {
+        a = Array.prototype.splice.call(a, 0, a.length);
+        return this.exec.apply(this, a);
+    }, true, true, true);
+
+    Fp.__defineProperty__('__construct__', function (a, x) {
+        switch (a.length) {
+          case 0:
+            return new this();
+          case 1:
+            return new this(a[0]);
+          case 2:
+            return new this(a[0], a[1]);
+          case 3:
+            return new this(a[0], a[1], a[2]);
+          case 4:
+            return new this(a[0], a[1], a[2], a[3]);
+          case 5:
+            return new this(a[0], a[1], a[2], a[3], a[4]);
+          case 6:
+            return new this(a[0], a[1], a[2], a[3], a[4], a[5]);
+          case 7:
+            return new this(a[0], a[1], a[2], a[3], a[4], a[5], a[6]);
+        }
+        throw "PANIC: too many arguments to constructor";
+    }, true, true, true);
+
+    // Since we use native functions such as Date along with host ones such
+    // as global.eval, we want both to be considered instances of the native
+    // Function constructor.
+    Fp.__defineProperty__('__hasInstance__', function (v) {
+        return v instanceof Function || v instanceof global.Function;
+    }, true, true, true);
+}
+
+function thunk(f, x) {
+    return function () { return f.__call__(this, arguments, x); };
+}
+
+function evaluate(s, f, l) {
+    if (typeof s != "string")
+        return s;
+
+    var x = ExecutionContext.current;
+    var x2 = new ExecutionContext(GLOBAL_CODE);
+    ExecutionContext.current = x2;
+    try {
+        execute(parse(s, f, l), x2);
+    } catch (e if e == THROW) {
+        if (x) {
+            x.result = x2.result;
+            throw THROW;
+        }
+        throw x2.result;
+    } finally {
+        ExecutionContext.current = x;
+    }
+    return x2.result;
+}

Propchange: incubator/xap/trunk/buildscripts/doctool/narcissus/jsexec.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/xap/trunk/buildscripts/doctool/narcissus/jsparse.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/buildscripts/doctool/narcissus/jsparse.js?rev=432045&view=auto
==============================================================================
--- incubator/xap/trunk/buildscripts/doctool/narcissus/jsparse.js (added)
+++ incubator/xap/trunk/buildscripts/doctool/narcissus/jsparse.js Wed Aug 16 14:57:09 2006
@@ -0,0 +1,984 @@
+/* vim: set sw=4 ts=8 et tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Narcissus JavaScript engine.
+ *
+ * The Initial Developer of the Original Code is
+ * Brendan Eich <br...@mozilla.org>.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Narcissus - JS implemented in JS.
+ *
+ * Lexical scanner and parser.
+ */
+
+// Build a regexp that recognizes operators and punctuators (except newline).
+var opRegExpSrc = "^";
+for (i in opTypeNames) {
+    if (i == '\n')
+        continue;
+    if (opRegExpSrc != "^")
+        opRegExpSrc += "|^";
+    opRegExpSrc += i.replace(/[?|^&(){}\[\]+\-*\/\.]/g, "\\$&");
+}
+var opRegExp = new RegExp(opRegExpSrc);
+
+// A regexp to match floating point literals (but not integer literals).
+var fpRegExp = /^\d+\.\d*(?:[eE][-+]?\d+)?|^\d+(?:\.\d*)?[eE][-+]?\d+|^\.\d+(?:[eE][-+]?\d+)?/;
+
+function Tokenizer(s, f, l) {
+    this.cursor = 0;
+    this.source = String(s);
+    this.tokens = [];
+    this.tokenIndex = 0;
+    this.lookahead = 0;
+    this.scanNewlines = false;
+    this.scanOperand = true;
+    this.filename = f || "";
+    this.lineno = l || 1;
+}
+
+Tokenizer.prototype = {
+    get input() {
+        return this.source.substring(this.cursor);
+    },
+
+    get done() {
+        return this.peek() == END;
+    },
+
+    get token() {
+        return this.tokens[this.tokenIndex];
+    },
+
+    match: function (tt) {
+        return this.get() == tt || this.unget();
+    },
+
+    mustMatch: function (tt) {
+        if (!this.match(tt))
+            throw this.newSyntaxError("Missing " + tokens[tt].toLowerCase());
+        return this.token;
+    },
+
+    peek: function () {
+        var tt;
+        if (this.lookahead) {
+            tt = this.tokens[(this.tokenIndex + this.lookahead) & 3].type;
+        } else {
+            tt = this.get();
+            this.unget();
+        }
+        return tt;
+    },
+
+    peekOnSameLine: function () {
+        this.scanNewlines = true;
+        var tt = this.peek();
+        this.scanNewlines = false;
+        return tt;
+    },
+
+    get: function () {
+        var token;
+        while (this.lookahead) {
+            --this.lookahead;
+            this.tokenIndex = (this.tokenIndex + 1) & 3;
+            token = this.tokens[this.tokenIndex];
+            if (token.type != NEWLINE || this.scanNewlines)
+                return token.type;
+        }
+
+        for (;;) {
+            var input = this.input;
+            var match = (this.scanNewlines ? /^[ \t]+/ : /^\s+/)(input);
+            if (match) {
+                var spaces = match[0];
+                this.cursor += spaces.length;
+                var newlines = spaces.match(/\n/g);
+                if (newlines)
+                    this.lineno += newlines.length;
+                input = this.input;
+            }
+
+            if (!(match = /^\/(?:\*(?:.|\n)*?\*\/|\/.*)/(input)))
+                break;
+            var comment = match[0];
+            this.cursor += comment.length;
+            newlines = comment.match(/\n/g);
+            if (newlines)
+                this.lineno += newlines.length
+        }
+
+        this.tokenIndex = (this.tokenIndex + 1) & 3;
+        token = this.tokens[this.tokenIndex];
+        if (!token)
+            this.tokens[this.tokenIndex] = token = {};
+
+        if (!input)
+            return token.type = END;
+
+        if ((match = fpRegExp(input))) {
+            token.type = NUMBER;
+            token.value = parseFloat(match[0]);
+        } else if ((match = /^0[xX][\da-fA-F]+|^0[0-7]*|^\d+/(input))) {
+            token.type = NUMBER;
+            token.value = parseInt(match[0]);
+        } else if ((match = /^\w+/(input))) {
+            var id = match[0];
+            token.type = keywords[id] || IDENTIFIER;
+            token.value = id;
+        } else if ((match = /^"(?:\\.|[^"])*"|^'(?:[^']|\\.)*'/(input))) { //"){
+            token.type = STRING;
+            token.value = eval(match[0]);
+        } else if (this.scanOperand &&
+                   (match = /^\/((?:\\.|[^\/])+)\/([gi]*)/(input))) {
+            token.type = REGEXP;
+            token.value = new RegExp(match[1], match[2]);
+        } else if ((match = opRegExp(input))) {
+            var op = match[0];
+            if (assignOps[op] && input[op.length] == '=') {
+                token.type = ASSIGN;
+                token.assignOp = GLOBAL[opTypeNames[op]];
+                match[0] += '=';
+            } else {
+                token.type = GLOBAL[opTypeNames[op]];
+                if (this.scanOperand &&
+                    (token.type == PLUS || token.type == MINUS)) {
+                    token.type += UNARY_PLUS - PLUS;
+                }
+                token.assignOp = null;
+            }
+            token.value = op;
+        } else {
+            throw this.newSyntaxError("Illegal token");
+        }
+
+        token.start = this.cursor;
+        this.cursor += match[0].length;
+        token.end = this.cursor;
+        token.lineno = this.lineno;
+        return token.type;
+    },
+
+    unget: function () {
+        if (++this.lookahead == 4) throw "PANIC: too much lookahead!";
+        this.tokenIndex = (this.tokenIndex - 1) & 3;
+    },
+
+    newSyntaxError: function (m) {
+        var e = new SyntaxError(m, this.filename, this.lineno);
+        e.source = this.source;
+        e.cursor = this.cursor;
+        return e;
+    }
+};
+
+function CompilerContext(inFunction) {
+    this.inFunction = inFunction;
+    this.stmtStack = [];
+    this.funDecls = [];
+    this.varDecls = [];
+}
+
+var CCp = CompilerContext.prototype;
+CCp.bracketLevel = CCp.curlyLevel = CCp.parenLevel = CCp.hookLevel = 0;
+CCp.ecmaStrictMode = CCp.inForLoopInit = false;
+
+function Script(t, x) {
+    var n = Statements(t, x);
+    n.type = SCRIPT;
+    n.funDecls = x.funDecls;
+    n.varDecls = x.varDecls;
+    return n;
+}
+
+// Node extends Array, which we extend slightly with a top-of-stack method.
+Array.prototype.__defineProperty__(
+    'top',
+    function () { 
+        return this.length && this[this.length-1]; 
+    },
+    false, false, true
+);
+
+function Node(t, type) {
+    var token = t.token;
+    if (token) {
+        this.type = type || token.type;
+        this.value = token.value;
+        this.lineno = token.lineno;
+        this.start = token.start;
+        this.end = token.end;
+    } else {
+        this.type = type;
+        this.lineno = t.lineno;
+    }
+    this.tokenizer = t;
+
+    for (var i = 2; i < arguments.length; i++)
+        this.push(arguments[i]);
+}
+
+var Np = Node.prototype = new Array;
+Np.constructor = Node;
+Np.toSource = Object.prototype.toSource;
+
+// Always use push to add operands to an expression, to update start and end.
+Np.push = function (kid) {
+    if (kid.start < this.start)
+        this.start = kid.start;
+    if (this.end < kid.end)
+        this.end = kid.end;
+    return Array.prototype.push.call(this, kid);
+}
+
+Node.indentLevel = 0;
+
+Np.toString = function () {
+    var a = [];
+    for (var i in this) {
+        if (this.hasOwnProperty(i) && i != 'type')
+            a.push({id: i, value: this[i]});
+    }
+    a.sort(function (a,b) { return (a.id < b.id) ? -1 : 1; });
+    const INDENTATION = "    ";
+    var n = ++Node.indentLevel;
+    var t = tokens[this.type];
+    var s = "{\n" + INDENTATION.repeat(n) +
+            "type: " + (/^\W/.test(t) ? opTypeNames[t] : t.toUpperCase());
+    for (i = 0; i < a.length; i++)
+        s += ",\n" + INDENTATION.repeat(n) + a[i].id + ": " + a[i].value;
+    n = --Node.indentLevel;
+    s += "\n" + INDENTATION.repeat(n) + "}";
+    return s;
+}
+
+Np.getSource = function () {
+    return this.tokenizer.source.slice(this.start, this.end);
+};
+
+Np.__defineGetter__('filename',
+                    function () { return this.tokenizer.filename; });
+
+String.prototype.repeat = function (n) {
+    var s = "", t = this + s;
+    while (--n >= 0)
+        s += t;
+    return s;
+}
+
+// Statement stack and nested statement handler.
+function nest(t, x, node, func, end) {
+    x.stmtStack.push(node);
+    var n = func(t, x);
+    x.stmtStack.pop();
+    end && t.mustMatch(end);
+    return n;
+}
+
+function Statements(t, x) {
+    var n = new Node(t, BLOCK);
+    x.stmtStack.push(n);
+    while (!t.done && t.peek() != RIGHT_CURLY)
+        n.push(Statement(t, x));
+    x.stmtStack.pop();
+    return n;
+}
+
+function Block(t, x) {
+    t.mustMatch(LEFT_CURLY);
+    var n = Statements(t, x);
+    t.mustMatch(RIGHT_CURLY);
+    return n;
+}
+
+const DECLARED_FORM = 0, EXPRESSED_FORM = 1, STATEMENT_FORM = 2;
+
+function Statement(t, x) {
+    var i, label, n, n2, ss, tt = t.get();
+
+    // Cases for statements ending in a right curly return early, avoiding the
+    // common semicolon insertion magic after this switch.
+    switch (tt) {
+      case FUNCTION:
+        return FunctionDefinition(t, x, true,
+                                  (x.stmtStack.length > 1)
+                                  ? STATEMENT_FORM
+                                  : DECLARED_FORM);
+
+      case LEFT_CURLY:
+        n = Statements(t, x);
+        t.mustMatch(RIGHT_CURLY);
+        return n;
+
+      case IF:
+        n = new Node(t);
+        n.condition = ParenExpression(t, x);
+        x.stmtStack.push(n);
+        n.thenPart = Statement(t, x);
+        n.elsePart = t.match(ELSE) ? Statement(t, x) : null;
+        x.stmtStack.pop();
+        return n;
+
+      case SWITCH:
+        n = new Node(t);
+        t.mustMatch(LEFT_PAREN);
+        n.discriminant = Expression(t, x);
+        t.mustMatch(RIGHT_PAREN);
+        n.cases = [];
+        n.defaultIndex = -1;
+        x.stmtStack.push(n);
+        t.mustMatch(LEFT_CURLY);
+        while ((tt = t.get()) != RIGHT_CURLY) {
+            switch (tt) {
+              case DEFAULT:
+                if (n.defaultIndex >= 0)
+                    throw t.newSyntaxError("More than one switch default");
+                // FALL THROUGH
+              case CASE:
+                n2 = new Node(t);
+                if (tt == DEFAULT)
+                    n.defaultIndex = n.cases.length;
+                else
+                    n2.caseLabel = Expression(t, x, COLON);
+                break;
+              default:
+                throw t.newSyntaxError("Invalid switch case");
+            }
+            t.mustMatch(COLON);
+            n2.statements = new Node(t, BLOCK);
+            while ((tt=t.peek()) != CASE && tt != DEFAULT && tt != RIGHT_CURLY)
+                n2.statements.push(Statement(t, x));
+            n.cases.push(n2);
+        }
+        x.stmtStack.pop();
+        return n;
+
+      case FOR:
+        n = new Node(t);
+        n.isLoop = true;
+        t.mustMatch(LEFT_PAREN);
+        if ((tt = t.peek()) != SEMICOLON) {
+            x.inForLoopInit = true;
+            if (tt == VAR || tt == CONST) {
+                t.get();
+                n2 = Variables(t, x);
+            } else {
+                n2 = Expression(t, x);
+            }
+            x.inForLoopInit = false;
+        }
+        if (n2 && t.match(IN)) {
+            n.type = FOR_IN;
+            if (n2.type == VAR) {
+                if (n2.length != 1) {
+                    throw new SyntaxError("Invalid for..in left-hand side",
+                                          t.filename, n2.lineno);
+                }
+
+                // NB: n2[0].type == IDENTIFIER and n2[0].value == n2[0].name.
+                n.iterator = n2[0];
+                n.varDecl = n2;
+            } else {
+                n.iterator = n2;
+                n.varDecl = null;
+            }
+            n.object = Expression(t, x);
+        } else {
+            n.setup = n2 || null;
+            t.mustMatch(SEMICOLON);
+            n.condition = (t.peek() == SEMICOLON) ? null : Expression(t, x);
+            t.mustMatch(SEMICOLON);
+            n.update = (t.peek() == RIGHT_PAREN) ? null : Expression(t, x);
+        }
+        t.mustMatch(RIGHT_PAREN);
+        n.body = nest(t, x, n, Statement);
+        return n;
+
+      case WHILE:
+        n = new Node(t);
+        n.isLoop = true;
+        n.condition = ParenExpression(t, x);
+        n.body = nest(t, x, n, Statement);
+        return n;
+
+      case DO:
+        n = new Node(t);
+        n.isLoop = true;
+        n.body = nest(t, x, n, Statement, WHILE);
+        n.condition = ParenExpression(t, x);
+        if (!x.ecmaStrictMode) {
+            // <script language="JavaScript"> (without version hints) may need
+            // automatic semicolon insertion without a newline after do-while.
+            // See http://bugzilla.mozilla.org/show_bug.cgi?id=238945.
+            t.match(SEMICOLON);
+            return n;
+        }
+        break;
+
+      case BREAK:
+      case CONTINUE:
+        n = new Node(t);
+        if (t.peekOnSameLine() == IDENTIFIER) {
+            t.get();
+            n.label = t.token.value;
+        }
+        ss = x.stmtStack;
+        i = ss.length;
+        label = n.label;
+        if (label) {
+            do {
+                if (--i < 0)
+                    throw t.newSyntaxError("Label not found");
+            } while (ss[i].label != label);
+        } else {
+            do {
+                if (--i < 0) {
+                    throw t.newSyntaxError("Invalid " + ((tt == BREAK)
+                                                         ? "break"
+                                                         : "continue"));
+                }
+            } while (!ss[i].isLoop && (tt != BREAK || ss[i].type != SWITCH));
+        }
+        n.target = ss[i];
+        break;
+
+      case TRY:
+        n = new Node(t);
+        n.tryBlock = Block(t, x);
+        n.catchClauses = [];
+        while (t.match(CATCH)) {
+            n2 = new Node(t);
+            t.mustMatch(LEFT_PAREN);
+            n2.varName = t.mustMatch(IDENTIFIER).value;
+            if (t.match(IF)) {
+                if (x.ecmaStrictMode)
+                    throw t.newSyntaxError("Illegal catch guard");
+                if (n.catchClauses.length && !n.catchClauses.top().guard)
+                    throw t.newSyntaxError("Guarded catch after unguarded");
+                n2.guard = Expression(t, x);
+            } else {
+                n2.guard = null;
+            }
+            t.mustMatch(RIGHT_PAREN);
+            n2.block = Block(t, x);
+            n.catchClauses.push(n2);
+        }
+        if (t.match(FINALLY))
+            n.finallyBlock = Block(t, x);
+        if (!n.catchClauses.length && !n.finallyBlock)
+            throw t.newSyntaxError("Invalid try statement");
+        return n;
+
+      case CATCH:
+      case FINALLY:
+        throw t.newSyntaxError(tokens[tt] + " without preceding try");
+
+      case THROW:
+        n = new Node(t);
+        n.exception = Expression(t, x);
+        break;
+
+      case RETURN:
+        if (!x.inFunction)
+            throw t.newSyntaxError("Invalid return");
+        n = new Node(t);
+        tt = t.peekOnSameLine();
+        if (tt != END && tt != NEWLINE && tt != SEMICOLON && tt != RIGHT_CURLY)
+            n.value = Expression(t, x);
+        break;
+
+      case WITH:
+        n = new Node(t);
+        n.object = ParenExpression(t, x);
+        n.body = nest(t, x, n, Statement);
+        return n;
+
+      case VAR:
+      case CONST:
+        n = Variables(t, x);
+        break;
+
+      case DEBUGGER:
+        n = new Node(t);
+        break;
+
+      case NEWLINE:
+      case SEMICOLON:
+        n = new Node(t, SEMICOLON);
+        n.expression = null;
+        return n;
+
+      default:
+        if (tt == IDENTIFIER && t.peek() == COLON) {
+            label = t.token.value;
+            ss = x.stmtStack;
+            for (i = ss.length-1; i >= 0; --i) {
+                if (ss[i].label == label)
+                    throw t.newSyntaxError("Duplicate label");
+            }
+            t.get();
+            n = new Node(t, LABEL);
+            n.label = label;
+            n.statement = nest(t, x, n, Statement);
+            return n;
+        }
+
+        n = new Node(t, SEMICOLON);
+        t.unget();
+        n.expression = Expression(t, x);
+        n.end = n.expression.end;
+        break;
+    }
+
+    if (t.lineno == t.token.lineno) {
+        tt = t.peekOnSameLine();
+        if (tt != END && tt != NEWLINE && tt != SEMICOLON && tt != RIGHT_CURLY)
+            throw t.newSyntaxError("Missing ; before statement");
+    }
+    t.match(SEMICOLON);
+    return n;
+}
+
+function FunctionDefinition(t, x, requireName, functionForm) {
+    var f = new Node(t);
+    if (f.type != FUNCTION)
+        f.type = (f.value == "get") ? GETTER : SETTER;
+    if (t.match(IDENTIFIER))
+        f.name = t.token.value;
+    else if (requireName)
+        throw t.newSyntaxError("Missing function identifier");
+
+    t.mustMatch(LEFT_PAREN);
+    f.params = [];
+    var tt;
+    while ((tt = t.get()) != RIGHT_PAREN) {
+        if (tt != IDENTIFIER)
+            throw t.newSyntaxError("Missing formal parameter");
+        f.params.push(t.token.value);
+        if (t.peek() != RIGHT_PAREN)
+            t.mustMatch(COMMA);
+    }
+
+    t.mustMatch(LEFT_CURLY);
+    var x2 = new CompilerContext(true);
+    f.body = Script(t, x2);
+    t.mustMatch(RIGHT_CURLY);
+    f.end = t.token.end;
+
+    f.functionForm = functionForm;
+    if (functionForm == DECLARED_FORM)
+        x.funDecls.push(f);
+    return f;
+}
+
+function Variables(t, x) {
+    var n = new Node(t);
+    do {
+        t.mustMatch(IDENTIFIER);
+        var n2 = new Node(t);
+        n2.name = n2.value;
+        if (t.match(ASSIGN)) {
+            if (t.token.assignOp)
+                throw t.newSyntaxError("Invalid variable initialization");
+            n2.initializer = Expression(t, x, COMMA);
+        }
+        n2.readOnly = (n.type == CONST);
+        n.push(n2);
+        x.varDecls.push(n2);
+    } while (t.match(COMMA));
+    return n;
+}
+
+function ParenExpression(t, x) {
+    t.mustMatch(LEFT_PAREN);
+    var n = Expression(t, x);
+    t.mustMatch(RIGHT_PAREN);
+    return n;
+}
+
+var opPrecedence = {
+    SEMICOLON: 0,
+    COMMA: 1,
+    ASSIGN: 2,
+    HOOK: 3, COLON: 3, CONDITIONAL: 3,
+    OR: 4,
+    AND: 5,
+    BITWISE_OR: 6,
+    BITWISE_XOR: 7,
+    BITWISE_AND: 8,
+    EQ: 9, NE: 9, STRICT_EQ: 9, STRICT_NE: 9,
+    LT: 10, LE: 10, GE: 10, GT: 10, IN: 10, INSTANCEOF: 10,
+    LSH: 11, RSH: 11, URSH: 11,
+    PLUS: 12, MINUS: 12,
+    MUL: 13, DIV: 13, MOD: 13,
+    DELETE: 14, VOID: 14, TYPEOF: 14, // PRE_INCREMENT: 14, PRE_DECREMENT: 14,
+    NOT: 14, BITWISE_NOT: 14, UNARY_PLUS: 14, UNARY_MINUS: 14,
+    INCREMENT: 15, DECREMENT: 15,     // postfix
+    NEW: 16,
+    DOT: 17
+};
+
+// Map operator type code to precedence.
+for (i in opPrecedence)
+    opPrecedence[GLOBAL[i]] = opPrecedence[i];
+
+var opArity = {
+    COMMA: -2,
+    ASSIGN: 2,
+    CONDITIONAL: 3,
+    OR: 2,
+    AND: 2,
+    BITWISE_OR: 2,
+    BITWISE_XOR: 2,
+    BITWISE_AND: 2,
+    EQ: 2, NE: 2, STRICT_EQ: 2, STRICT_NE: 2,
+    LT: 2, LE: 2, GE: 2, GT: 2, IN: 2, INSTANCEOF: 2,
+    LSH: 2, RSH: 2, URSH: 2,
+    PLUS: 2, MINUS: 2,
+    MUL: 2, DIV: 2, MOD: 2,
+    DELETE: 1, VOID: 1, TYPEOF: 1,  // PRE_INCREMENT: 1, PRE_DECREMENT: 1,
+    NOT: 1, BITWISE_NOT: 1, UNARY_PLUS: 1, UNARY_MINUS: 1,
+    INCREMENT: 1, DECREMENT: 1,     // postfix
+    NEW: 1, NEW_WITH_ARGS: 2, DOT: 2, INDEX: 2, CALL: 2,
+    ARRAY_INIT: 1, OBJECT_INIT: 1, GROUP: 1
+};
+
+// Map operator type code to arity.
+for (i in opArity)
+    opArity[GLOBAL[i]] = opArity[i];
+
+function Expression(t, x, stop) {
+    var n, id, tt, operators = [], operands = [];
+    var bl = x.bracketLevel, cl = x.curlyLevel, pl = x.parenLevel,
+        hl = x.hookLevel;
+
+    function reduce() {
+        var n = operators.pop();
+        var op = n.type;
+        var arity = opArity[op];
+        if (arity == -2) {
+            // Flatten left-associative trees.
+            var left = operands.length >= 2 && operands[operands.length-2];
+            if (left.type == op) {
+                var right = operands.pop();
+                left.push(right);
+                return left;
+            }
+            arity = 2;
+        }
+
+        // Always use push to add operands to n, to update start and end.
+        var a = operands.splice(operands.length - arity);
+        for (var i = 0; i < arity; i++)
+            n.push(a[i]);
+
+        // Include closing bracket or postfix operator in [start,end).
+        if (n.end < t.token.end)
+            n.end = t.token.end;
+
+        operands.push(n);
+        return n;
+    }
+
+loop:
+    while ((tt = t.get()) != END) {
+        if (tt == stop &&
+            x.bracketLevel == bl && x.curlyLevel == cl && x.parenLevel == pl &&
+            x.hookLevel == hl) {
+            // Stop only if tt matches the optional stop parameter, and that
+            // token is not quoted by some kind of bracket.
+            break;
+        }
+        switch (tt) {
+          case SEMICOLON:
+            // NB: cannot be empty, Statement handled that.
+            break loop;
+
+          case ASSIGN:
+          case HOOK:
+          case COLON:
+            if (t.scanOperand)
+                break loop;
+            // Use >, not >=, for right-associative ASSIGN and HOOK/COLON.
+            while (opPrecedence[operators.top().type] > opPrecedence[tt])
+                reduce();
+            if (tt == COLON) {
+                n = operators.top();
+                if (n.type != HOOK)
+                    throw t.newSyntaxError("Invalid label");
+                n.type = CONDITIONAL;
+                --x.hookLevel;
+            } else {
+                operators.push(new Node(t));
+                if (tt == ASSIGN)
+                    operands.top().assignOp = t.token.assignOp;
+                else
+                    ++x.hookLevel;      // tt == HOOK
+            }
+            t.scanOperand = true;
+            break;
+
+          case IN:
+            // An in operator should not be parsed if we're parsing the head of
+            // a for (...) loop, unless it is in the then part of a conditional
+            // expression, or parenthesized somehow.
+            if (x.inForLoopInit && !x.hookLevel &&
+                !x.bracketLevel && !x.curlyLevel && !x.parenLevel) {
+                break loop;
+            }
+            // FALL THROUGH
+          case COMMA:
+            // Treat comma as left-associative so reduce can fold left-heavy
+            // COMMA trees into a single array.
+            // FALL THROUGH
+          case OR:
+          case AND:
+          case BITWISE_OR:
+          case BITWISE_XOR:
+          case BITWISE_AND:
+          case EQ: case NE: case STRICT_EQ: case STRICT_NE:
+          case LT: case LE: case GE: case GT:
+          case INSTANCEOF:
+          case LSH: case RSH: case URSH:
+          case PLUS: case MINUS:
+          case MUL: case DIV: case MOD:
+          case DOT:
+            if (t.scanOperand)
+                break loop;
+            while (opPrecedence[operators.top().type] >= opPrecedence[tt])
+                reduce();
+            if (tt == DOT) {
+                t.mustMatch(IDENTIFIER);
+                operands.push(new Node(t, DOT, operands.pop(), new Node(t)));
+            } else {
+                operators.push(new Node(t));
+                t.scanOperand = true;
+            }
+            break;
+
+          case DELETE: case VOID: case TYPEOF:
+          case NOT: case BITWISE_NOT: case UNARY_PLUS: case UNARY_MINUS:
+          case NEW:
+            if (!t.scanOperand)
+                break loop;
+            operators.push(new Node(t));
+            break;
+
+          case INCREMENT: case DECREMENT:
+            if (t.scanOperand) {
+                operators.push(new Node(t));  // prefix increment or decrement
+            } else {
+                // Use >, not >=, so postfix has higher precedence than prefix.
+                while (opPrecedence[operators.top().type] > opPrecedence[tt])
+                    reduce();
+                n = new Node(t, tt, operands.pop());
+                n.postfix = true;
+                operands.push(n);
+            }
+            break;
+
+          case FUNCTION:
+            if (!t.scanOperand)
+                break loop;
+            operands.push(FunctionDefinition(t, x, false, EXPRESSED_FORM));
+            t.scanOperand = false;
+            break;
+
+          case NULL: case THIS: case TRUE: case FALSE:
+          case IDENTIFIER: case NUMBER: case STRING: case REGEXP:
+            if (!t.scanOperand)
+                break loop;
+            operands.push(new Node(t));
+            t.scanOperand = false;
+            break;
+
+          case LEFT_BRACKET:
+            if (t.scanOperand) {
+                // Array initialiser.  Parse using recursive descent, as the
+                // sub-grammar here is not an operator grammar.
+                n = new Node(t, ARRAY_INIT);
+                while ((tt = t.peek()) != RIGHT_BRACKET) {
+                    if (tt == COMMA) {
+                        t.get();
+                        n.push(null);
+                        continue;
+                    }
+                    n.push(Expression(t, x, COMMA));
+                    if (!t.match(COMMA))
+                        break;
+                }
+                t.mustMatch(RIGHT_BRACKET);
+                operands.push(n);
+                t.scanOperand = false;
+            } else {
+                // Property indexing operator.
+                operators.push(new Node(t, INDEX));
+                t.scanOperand = true;
+                ++x.bracketLevel;
+            }
+            break;
+
+          case RIGHT_BRACKET:
+            if (t.scanOperand || x.bracketLevel == bl)
+                break loop;
+            while (reduce().type != INDEX)
+                continue;
+            --x.bracketLevel;
+            break;
+
+          case LEFT_CURLY:
+            if (!t.scanOperand)
+                break loop;
+            // Object initialiser.  As for array initialisers (see above),
+            // parse using recursive descent.
+            ++x.curlyLevel;
+            n = new Node(t, OBJECT_INIT);
+          object_init:
+            if (!t.match(RIGHT_CURLY)) {
+                do {
+                    tt = t.get();
+                    if ((t.token.value == "get" || t.token.value == "set") &&
+                        t.peek() == IDENTIFIER) {
+                        if (x.ecmaStrictMode)
+                            throw t.newSyntaxError("Illegal property accessor");
+                        n.push(FunctionDefinition(t, x, true, EXPRESSED_FORM));
+                    } else {
+                        switch (tt) {
+                          case IDENTIFIER:
+                          case NUMBER:
+                          case STRING:
+                            id = new Node(t);
+                            break;
+                          case RIGHT_CURLY:
+                            if (x.ecmaStrictMode)
+                                throw t.newSyntaxError("Illegal trailing ,");
+                            break object_init;
+                          default:
+                            throw t.newSyntaxError("Invalid property name");
+                        }
+                        t.mustMatch(COLON);
+                        n.push(new Node(t, PROPERTY_INIT, id,
+                                        Expression(t, x, COMMA)));
+                    }
+                } while (t.match(COMMA));
+                t.mustMatch(RIGHT_CURLY);
+            }
+            operands.push(n);
+            t.scanOperand = false;
+            --x.curlyLevel;
+            break;
+
+          case RIGHT_CURLY:
+            if (!t.scanOperand && x.curlyLevel != cl)
+                throw "PANIC: right curly botch";
+            break loop;
+
+          case LEFT_PAREN:
+            if (t.scanOperand) {
+                operators.push(new Node(t, GROUP));
+            } else {
+                while (opPrecedence[operators.top().type] > opPrecedence[NEW])
+                    reduce();
+
+                // Handle () now, to regularize the n-ary case for n > 0.
+                // We must set scanOperand in case there are arguments and
+                // the first one is a regexp or unary+/-.
+                n = operators.top();
+                t.scanOperand = true;
+                if (t.match(RIGHT_PAREN)) {
+                    if (n.type == NEW) {
+                        --operators.length;
+                        n.push(operands.pop());
+                    } else {
+                        n = new Node(t, CALL, operands.pop(),
+                                     new Node(t, LIST));
+                    }
+                    operands.push(n);
+                    t.scanOperand = false;
+                    break;
+                }
+                if (n.type == NEW)
+                    n.type = NEW_WITH_ARGS;
+                else
+                    operators.push(new Node(t, CALL));
+            }
+            ++x.parenLevel;
+            break;
+
+          case RIGHT_PAREN:
+            if (t.scanOperand || x.parenLevel == pl)
+                break loop;
+            while ((tt = reduce().type) != GROUP && tt != CALL &&
+                   tt != NEW_WITH_ARGS) {
+                continue;
+            }
+            if (tt != GROUP) {
+                n = operands.top();
+                if (n[1].type != COMMA)
+                    n[1] = new Node(t, LIST, n[1]);
+                else
+                    n[1].type = LIST;
+            }
+            --x.parenLevel;
+            break;
+
+          // Automatic semicolon insertion means we may scan across a newline
+          // and into the beginning of another statement.  If so, break out of
+          // the while loop and let the t.scanOperand logic handle errors.
+          default:
+            break loop;
+        }
+    }
+
+    if (x.hookLevel != hl)
+        throw t.newSyntaxError("Missing : after ?");
+    if (t.scanOperand)
+        throw t.newSyntaxError("Missing operand");
+
+    // Resume default mode, scanning for operands, not operators.
+    t.scanOperand = true;
+    t.unget();
+    while (operators.length)
+        reduce();
+    return operands.pop();
+}
+
+function parse(s, f, l) {
+    var t = new Tokenizer(s, f, l);
+    var x = new CompilerContext(false);
+    var n = Script(t, x);
+    if (!t.done)
+        throw t.newSyntaxError("Syntax error");
+    return n;
+}

Propchange: incubator/xap/trunk/buildscripts/doctool/narcissus/jsparse.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/xap/trunk/buildscripts/dojoGuardEnd.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/buildscripts/dojoGuardEnd.js?rev=432045&view=auto
==============================================================================
--- incubator/xap/trunk/buildscripts/dojoGuardEnd.js (added)
+++ incubator/xap/trunk/buildscripts/dojoGuardEnd.js Wed Aug 16 14:57:09 2006
@@ -0,0 +1 @@
+};

Propchange: incubator/xap/trunk/buildscripts/dojoGuardEnd.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/xap/trunk/buildscripts/dojoGuardStart.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/buildscripts/dojoGuardStart.js?rev=432045&view=auto
==============================================================================
--- incubator/xap/trunk/buildscripts/dojoGuardStart.js (added)
+++ incubator/xap/trunk/buildscripts/dojoGuardStart.js Wed Aug 16 14:57:09 2006
@@ -0,0 +1 @@
+if(typeof dojo == "undefined"){

Propchange: incubator/xap/trunk/buildscripts/dojoGuardStart.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/xap/trunk/buildscripts/externalconfig.mak
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/buildscripts/externalconfig.mak?rev=432045&view=auto
==============================================================================
--- incubator/xap/trunk/buildscripts/externalconfig.mak (added)
+++ incubator/xap/trunk/buildscripts/externalconfig.mak Wed Aug 16 14:57:09 2006
@@ -0,0 +1,95 @@
+#
+# you probably need to override some variables in this file, unless everything is in your path
+#
+
+PERL     := perl -w
+CP       := cp
+
+####
+# JS javascript interpreter
+####
+JS = js -w -s
+JSNAME = spidermonkey
+
+# spidermonkey
+#SPIDER_DIR= /Applications/js/src/Darwin_DBG.OBJ
+#SPIDER_DIR= /Users/mda/bin
+#JS = $(SPIDER_DIR)/js -w -s
+
+# or xpcshell
+#MOZ_DIR = /tmp/mozilla
+#JS = $(MOZ_DIR)/run-mozilla.sh $(MOZ_DIR)/xpcshell -w
+
+# or rhino
+RHINO_OPT=-opt -1 #
+RHINO_OPT=#
+#RHINO_DIR = /Applications/rhino1_5R5pre
+#RHINO_DIR = /Users/mda/Desktop/rhino1_5R4_1
+RHINO_DIR = /Users/mda/Desktop/rhino1_5R5
+#RHINO_DIR = /Users/mda/workspaces/mozilla/js/rhino/build/rhino1_5R5pre
+# RHINO_CP is only needed for the JsLinker project
+RHINO_CP   :=-classpath $(RHINO_DIR)/js.jar
+#JS = java -jar $(RHINO_DIR)/js.jar
+#JSNAME = rhino
+
+# or windows cscript
+#JSNAME = wsh
+
+# or kjs
+#JS = /home/mda/shared/src/javascript/JavaScriptCore/kjs/testkjs.linux
+# JS = /Users/mda/Desktop/JavaScriptCore/kjs/kjs
+
+####
+# JSC
+####
+# Rotor (shared source JScript .NET)
+# JSC_DIR := /users/mda/workspaces/sscli/build/v1.ppcfstchk.rotor/
+JSC_DIR := /users/mda/workspaces/sscli/build/v1.ppcfstchk.rotor/
+JSC_DIR := /usr/local/src/sscli_linux_20020821/clr/src/tools/
+CLIX := $(JSC_DIR)clix
+JSC := $(CLIX) $(JSC_DIR)jsc.exe
+
+####
+# DOXYGEN
+####
+DOXYGEN = doxygen
+
+#####
+# DOT (from graphviz)
+####
+DOT = dot
+#DOT = `which dot 2>/dev/null`
+
+####
+# POD2HTML (for extracting source comment from .pod or .pl files)
+####
+# must use $< as input and $@ as output
+# there is no way to turn off pod2html's double quote conversion, so we post process
+POD2HTML = pod2html --verbose --norecurse --podroot=$(DOCSRC_DIR) --infile=$< --css=burstsite.css | perl -pe "s/\`\`/\"/g; s/\'\'/\"/g" > $@
+
+####
+# rst2html (for converting reStructuredText to html)
+####
+# from http://docutils.sourceforge.net
+RST2HTML := rst2html.py
+
+####
+# xsltproc (for doing docbook processing)
+# from http://xmlsoft.org/XSLT/xsltproc2.html
+####
+XSLTPROC := xsltproc
+
+####
+# docbook-xsl
+# from http://docbook.sourceforge.net
+####
+
+# "apt-get install docbook-xsl" puts it here.
+DOCBOOK_XSL := /usr/share/xml/docbook/stylesheet/nwalsh/xhtml/docbook.xsl
+
+# docbook dtd is for validation. 
+# "apt-get install docbook" puts it here.
+DOCBOOK_DTD_DIR := /usr/share/sgml/docbook/dtd/4.3
+
+
+

Added: incubator/xap/trunk/buildscripts/foo-bard-ant.txt
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/buildscripts/foo-bard-ant.txt?rev=432045&view=auto
==============================================================================
--- incubator/xap/trunk/buildscripts/foo-bard-ant.txt (added)
+++ incubator/xap/trunk/buildscripts/foo-bard-ant.txt Wed Aug 16 14:57:09 2006
@@ -0,0 +1,7 @@
+in order to get ant working w/ BSF, Rhino, and Jython on a fresh SuSE 9.2
+install, it was necessaray to invoke Ant w/ the following command line:
+
+	alex@linux:~/dojo/buildscripts> CLASSPATH="/home/alex/.ant/lib/js.jar:/home/alex/.ant/lib/jython.jar" ant testScripting
+
+I'm still investigating why this might be, but needless to say it throws into
+doubt the entire reason for the -check-config and -fix-config tasks. Grr.

Propchange: incubator/xap/trunk/buildscripts/foo-bard-ant.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/xap/trunk/buildscripts/getDependencyList.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/buildscripts/getDependencyList.js?rev=432045&view=auto
==============================================================================
--- incubator/xap/trunk/buildscripts/getDependencyList.js (added)
+++ incubator/xap/trunk/buildscripts/getDependencyList.js Wed Aug 16 14:57:09 2006
@@ -0,0 +1,15 @@
+/* 
+	params: 
+		hostenvType: 
+			we expect to have hostenvType defined, but we provide "browser" if
+			it's not defined.
+		dependencies:
+			an Array of strings in the form normally accepted by
+			dojo.hostenv.loadModule("..."), although it is acceptable to
+			include the whole loadModule("...") call.
+*/
+
+load('buildUtil.js');
+
+// print(dojo.hostenv.loadedUris.join(",\n"));
+print(buildUtil.getDependencyList(this['dependencies'], this['hostenvType']).join(",\n"));

Propchange: incubator/xap/trunk/buildscripts/getDependencyList.js
------------------------------------------------------------------------------
    svn:eol-style = native