var types = require('./types'),
readline = require('./node_readline'),
reader = require('./reader'),
- printer = require('./printer');
+ printer = require('./printer'),
+ interop = require('./interop');
}
// Errors/Exceptions
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 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,
'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;