mirror of
https://github.com/samsonjs/elisp.js.git
synced 2026-03-25 09:15:49 +00:00
143 lines
2.8 KiB
JavaScript
143 lines
2.8 KiB
JavaScript
////
|
|
// Emacs Lisp implementation in JavaScript.
|
|
//
|
|
// Copyright (c) 2009 Sami Samhuri - sami.samhuri@gmail.com
|
|
//
|
|
// Released under the terms of the MIT license. See the included file
|
|
// LICENSE.
|
|
|
|
/****************************************************************
|
|
**** Utilities *************************************************
|
|
****************************************************************/
|
|
|
|
elisp.Util = function(){};
|
|
|
|
// aka foldl
|
|
elisp.Util.reduce = function(fn, accum, list) {
|
|
var i = 0,
|
|
n = list.length;
|
|
while (i < n) {
|
|
accum = fn(accum, list[i++]);
|
|
}
|
|
return accum;
|
|
};
|
|
|
|
elisp.Util.foldr = function(fn, end, list) {
|
|
var i = list.length-1;
|
|
while (i >= 0) {
|
|
end = fn(list[i--], end);
|
|
}
|
|
return end;
|
|
};
|
|
|
|
elisp.Util.shallowCopy = function(list) {
|
|
var i = 0,
|
|
n = list.length,
|
|
result = [];
|
|
while (i < n) {
|
|
result.push(list[i++]);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
|
|
// i'm sorry
|
|
elisp.Util.pp = function(x, indent, key, noprint) {
|
|
if (indent === undefined) {
|
|
indent = 0;
|
|
}
|
|
|
|
/* string to print at the end, the only way to print 2 strings in
|
|
* succession without a newline is to buffer them
|
|
*/
|
|
var buffer = "";
|
|
var printB = function(s, newline) {
|
|
buffer += s;
|
|
if (newline) buffer += "\n";
|
|
};
|
|
var dumpBuffer = function(b) {
|
|
if (b === undefined) b = buffer;
|
|
if (buffer.length <= 72) {
|
|
print(buffer);
|
|
}
|
|
else {
|
|
var split = 72;
|
|
var c;
|
|
while ((c = b[split]) && c.match(/[a-zA-Z0-9"'\[\]_-]/)) --split;
|
|
print(b.substring(0, split));
|
|
var next_chunk = b.substring(split);
|
|
if (next_chunk) dumpBuffer(next_chunk);
|
|
}
|
|
buffer = "";
|
|
};
|
|
|
|
var space = "";
|
|
// for (var j = 0; j < indent; j++) {
|
|
// space += " ";
|
|
// }
|
|
|
|
switch (elisp.typeOf(x)) {
|
|
case 'object':
|
|
if (key) {
|
|
printB(space + key + ': {');
|
|
}
|
|
else {
|
|
printB(space + ' {');
|
|
}
|
|
for (var a in x) {
|
|
printB(elisp.Util.pp(x[a], 1+indent, a, true));
|
|
printB(', ');
|
|
}
|
|
printB(space + "} ");
|
|
break;
|
|
|
|
case 'string':
|
|
if (key) {
|
|
printB(space + key + ': "' + x + '"');
|
|
}
|
|
else {
|
|
printB(space + '"' + x + '"');
|
|
}
|
|
return buffer;
|
|
|
|
case 'array':
|
|
// nil special case
|
|
if (x.length == 2 && elisp.tag(x) == 'symbol' && elisp.val(x) == 'nil') {
|
|
return elisp.Util.pp(null, indent, key);
|
|
}
|
|
|
|
if (key) {
|
|
printB(space + key + ': [');
|
|
}
|
|
else {
|
|
printB(space + '[');
|
|
}
|
|
var n = x.length, i = 0;
|
|
while (i < n) {
|
|
if (i > 0) printB(', ');
|
|
printB(elisp.Util.pp(x[i++], 1+indent, undefined, true));
|
|
}
|
|
printB(space + ']');
|
|
break;
|
|
|
|
case 'null':
|
|
if (key) {
|
|
printB(space + key + ': (null)');
|
|
}
|
|
else {
|
|
printB(space + '(null)');
|
|
}
|
|
return buffer;
|
|
|
|
default:
|
|
if (key) {
|
|
printB(space + key + ": " + x);
|
|
}
|
|
else {
|
|
printB(space + x);
|
|
}
|
|
return buffer;
|
|
}
|
|
if (noprint) return buffer;
|
|
else dumpBuffer();
|
|
};
|