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