var types = require('./types'),
readline = require('./node_readline'),
reader = require('./reader'),
- printer = require('./printer');
+ printer = require('./printer'),
+ interop = require('./interop');
}
// Errors/Exceptions
}
function slurp(f) {
- return require('fs').readFileSync(f, 'utf-8');
+ if (typeof require !== 'undefined') {
+ return require('fs').readFileSync(f, 'utf-8');
+ } else {
+ var req = new XMLHttpRequest();
+ req.open("GET", f, false);
+ req.send();
+ if (req.status == 200) {
+ return req.responseText;
+ } else {
+ throw new Error("Failed to slurp file: " + f);
+ }
+ }
}
return lst.concat.apply(lst, Array.prototype.slice.call(arguments, 1));
}
-function nth(lst, idx) { return lst[idx]; }
+function nth(lst, idx) {
+ if (idx < lst.length) { return lst[idx]; }
+ else { throw new Error("nth: index out of range"); }
+}
-function first(lst) { return lst[0]; }
+function first(lst) { return (lst === null) ? null : lst[0]; }
-function rest(lst) { return lst.slice(1); }
+function rest(lst) { return (lst == null) ? [] : lst.slice(1); }
function empty_Q(lst) { return lst.length === 0; }
function count(s) {
if (Array.isArray(s)) { return s.length; }
- else { return Object.keys(s).length; }
+ else if (s === null) { return 0; }
+ else { return Object.keys(s).length; }
}
function conj(lst) {
}
}
+function seq(obj) {
+ if (types._list_Q(obj)) {
+ return obj.length > 0 ? obj : null;
+ } else if (types._vector_Q(obj)) {
+ return obj.length > 0 ? Array.prototype.slice.call(obj, 0): null;
+ } else if (types._string_Q(obj)) {
+ return obj.length > 0 ? obj.split('') : null;
+ } else if (obj === null) {
+ return null;
+ } else {
+ throw new Error("seq: called on non-sequence");
+ }
+}
+
+
function apply(f) {
var args = Array.prototype.slice.call(arguments, 1);
return f.apply(f, args.slice(0, args.length-1).concat(args[args.length-1]));
return atm.val;
}
+function js_eval(str) {
+ return interop.js_to_mal(eval(str.toString()));
+}
+
+function js_method_call(object_method_str) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ r = interop.resolve_js(object_method_str),
+ obj = r[0], f = r[1];
+ var res = f.apply(obj, args);
+ return interop.js_to_mal(res);
+}
// types.ns is namespace of type functions
var ns = {'type': types._obj_type,
'nil?': types._nil_Q,
'true?': types._true_Q,
'false?': types._false_Q,
+ 'string?': types._string_Q,
'symbol': types._symbol,
'symbol?': types._symbol_Q,
+ 'keyword': types._keyword,
+ 'keyword?': types._keyword_Q,
'pr-str': pr_str,
'str': str,
'count': count,
'apply': apply,
'map': map,
+
'conj': conj,
+ 'seq': seq,
'with-meta': with_meta,
'meta': meta,
'atom?': types._atom_Q,
"deref": deref,
"reset!": reset_BANG,
- "swap!": swap_BANG};
+ "swap!": swap_BANG,
+
+ 'js-eval': js_eval,
+ '.': js_method_call
+};
exports.ns = core.ns = ns;