blob: 60c8a0c8e6b0768d0f66bbe06c42ee2b9e7024cb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Simple utility functions.
*/
/**
* Scheme-like lists.
*/
function cons(car, cdr) {
var a = new Array();
a.push(car);
return a.concat(cdr);
}
function car(l) {
return l[0];
}
function first(l) {
return l[0];
}
function cdr(l) {
return l.slice(1);
}
function rest(l) {
return l.slice(1);
}
function cadr(l) {
return l[1];
}
function cddr(l) {
return l.slice(2);
}
function caddr(l) {
return l[2];
}
function cdddr(l) {
return l.slice(3);
}
function cadddr(l) {
return l[3];
}
function append(a, b) {
return a.concat(b);
}
function reverse(l) {
return l.slice(0).reverse();
}
function range(a, b) {
var l = new Array();
for (var x = a; x < b; x++)
l.push(x);
return l;
}
function isNil(v) {
return (v == null || typeof v == 'undefined' || (v.constructor == Array && v.length == 0));
}
function isSymbol(v) {
return (typeof v == 'string' && v.slice(0, 1) == "'");
}
function isString(v) {
return (typeof v == 'string' && v.slice(0, 1) != "'");
}
function isList(v) {
return (v != null && typeof v != 'undefined' && v.constructor == Array);
}
function isTaggedList(v, t) {
return (isList(v) && !isNil(v) && car(v) == t);
}
var emptylist = new Array();
function mklist() {
if (arguments.length == 0)
return emptylist;
var a = new Array();
for (i = 0; i < arguments.length; i++)
a[i] = arguments[i];
return a;
}
function length(l) {
return l.length;
}
/**
* Scheme-like associations.
*/
function assoc(k, l) {
if (isNil(l))
return emptylist;
var n = l.length;
for(var i = 0; i < n; i++) {
if (k == car(l[i]))
return l[i];
}
return emptylist;
}
/**
* Map, filter and reduce functions.
*/
function map(f, l) {
if (isNil(l))
return l;
var n = l.length;
var a = new Array();
for(var i = 0; i < n; i++) {
a.push(f(l[i]));
}
return a;
}
function filter(f, l) {
if (isNil(l))
return l;
var n = l.length;
var a = new Array();
for(var i = 0; i < n; i++) {
if (f(l[i]))
a.push(l[i]);
}
return a;
}
function reduce(f, i, l) {
if (isNil(l))
return i;
return reduce(f, f(i, car(l)), cdr(l));
}
/**
* Split a path into a list of segments.
*/
function tokens(path) {
return filter(function(s) { return length(s) != 0; }, path.split("/"));
}
/**
* Log a value.
*/
var rconsole;
function log(v) {
try {
var s = '';
for (i = 0; i < arguments.length; i++) {
s = s + writeValue(arguments[i]);
if (i < arguments.length)
s = s + ' ';
}
if (rconsole) {
try {
rconsole.log(s);
} catch (e) {}
}
try {
console.log(s);
} catch (e) {}
} catch (e) {}
return true;
}
/**
* Dump an object to the debug console.
*/
function debug(o) {
try {
for (f in o) {
try {
log('debug ' + f + '=' + o[f]);
} catch (e) {}
}
} catch (e) {}
return true;
}
/**
* Return true if the current browser is Internet Explorer.
*/
function isIE() {
if (typeof isIE.detected != 'undefined')
return isIE.detected;
isIE.detected = navigator.appName == 'Microsoft Internet Explorer';
return isIE.detected;
};
/**
* External build configuration.
*/
var config;
if (isNil(config))
config = {};
/**
* Simple assert function.
*/
function AssertException() {
}
AssertException.prototype.toString = function () {
return 'AssertException';
};
function assert(exp) {
if (!exp)
throw new AssertException();
}
/**
* Write a list of strings.
*/
function writeStrings(l) {
if (isNil(l))
return '';
var s = '';
var n = l.length;
for(var i = 0; i < n; i++) {
s = s + l[i];
}
return s;
}
/**
* Write a value using a Scheme-like syntax.
*/
function writeValue(v) {
function writePrimitive(p) {
if (isSymbol(p))
return '' + p.substring(1);
if (isString(p))
return '"' + p + '"';
return '' + p;
}
function writeList(l) {
if (isNil(l))
return '';
return ' ' + writeValue(car(l)) + writeList(cdr(l));
}
if (!isList(v))
return writePrimitive(v);
if (isNil(v))
return '()';
return '(' + writeValue(car(v)) + writeList(cdr(v)) + ')';
}
/**
* Apply a function and memoize its result.
*/
function memo(obj, key, f) {
if (!('memo' in obj)) {
obj.memo = {};
return obj.memo[key] = f();
}
if (key in obj.memo)
return obj.memo[key];
return obj.memo[key] = f();
}
/**
* Un-memoize stored results.
*/
function unmemo(obj) {
obj.memo = {};
return true;
}
/**
* Returns a list of the properties of an object.
*/
function properties(o) {
var a = new Array();
for (p in o)
a.push(p);
return a;
}
/**
* Convert a host name to a domain name.
*/
function domainname(host) {
var ds = host.indexOf('//');
if (ds != -1)
return domainname(host.substring(ds + 2));
var s = host.indexOf('/');
if (s != -1)
return domainname(host.substring(0, s));
var h = reverse(host.split('.'));
var d = (!isNil(cddr(h)) && caddr(h) == 'www')? mklist(car(h), cadr(h), caddr(h)) : mklist(car(h), cadr(h));
return reverse(d).join('.');
}
/**
* Return true if a host name is a subdomain.
*/
function issubdomain(host) {
return host.split('.').length > 2;
}
/**
* Format a string like Python format.
*/
function format() {
var i = 0;
var s = '';
for (a in arguments) {
s = i == 0? arguments[a] : s.replace('{' + a + '}', arguments[a]);
i++;
}
return s;
}
/**
* Functions with side effects. Use with moderation.
*/
/**
* Set the car of a list.
*/
function setcar(l, v) {
l[0] = v;
return l;
}
/**
* Set the cadr of a list.
*/
function setcadr(l, v) {
l[1] = v;
return l;
}
/**
* Set the caddr of a list.
*/
function setcaddr(l, v) {
l[2] = v;
return l;
}
/**
* Append the elements of a list to a list.
*/
function setappend(a, b) {
if (isNil(b))
return a;
a.push(car(b));
return setappend(a, cdr(b));
}
/**
* Set the cdr of a list.
*/
function setcdr(a, b) {
a.length = 1;
return setappend(a, b);
}
/**
* Set the contents of a list.
*/
function setlist(a, b) {
if (b == a)
return b;
a.length = 0;
return setappend(a, b);
}