1 // Node vs browser behavior
3 if (typeof module
=== 'undefined') {
9 function _obj_type(obj
) {
10 if (_symbol_Q(obj
)) { return 'symbol'; }
11 else if (_list_Q(obj
)) { return 'list'; }
12 else if (_vector_Q(obj
)) { return 'vector'; }
13 else if (_hash_map_Q(obj
)) { return 'hash-map'; }
14 else if (_nil_Q(obj
)) { return 'nil'; }
15 else if (_true_Q(obj
)) { return 'true'; }
16 else if (_false_Q(obj
)) { return 'false'; }
17 else if (_atom_Q(obj
)) { return 'atom'; }
19 switch (typeof(obj
)) {
20 case 'number': return 'number';
21 case 'function': return 'function';
22 case 'string': return obj
[0] == '\u029e' ? 'keyword' : 'string';
23 default: throw new Error("Unknown type '" + typeof(obj
) + "'");
28 function _sequential_Q(lst
) { return _list_Q(lst
) || _vector_Q(lst
); }
31 function _equal_Q (a
, b
) {
32 var ota
= _obj_type(a
), otb
= _obj_type(b
);
33 if (!(ota
=== otb
|| (_sequential_Q(a
) && _sequential_Q(b
)))) {
37 case 'symbol': return a
.value
=== b
.value
;
40 if (a
.length
!== b
.length
) { return false; }
41 for (var i
=0; i
<a
.length
; i
++) {
42 if (! _equal_Q(a
[i
], b
[i
])) { return false; }
46 if (Object
.keys(a
).length
!== Object
.keys(b
).length
) { return false; }
48 if (! _equal_Q(a
[k
], b
[k
])) { return false; }
57 function _clone (obj
) {
59 switch (_obj_type(obj
)) {
61 new_obj
= obj
.slice(0);
64 new_obj
= obj
.slice(0);
65 new_obj
.__isvector__
= true;
70 if (obj
.hasOwnProperty(k
)) { new_obj
[k
] = obj
[k
]; }
74 new_obj
= obj
.clone();
77 throw new Error("clone of non-collection: " + _obj_type(obj
));
79 Object
.defineProperty(new_obj
, "__meta__", {
88 function _nil_Q(a
) { return a
=== null ? true : false; }
89 function _true_Q(a
) { return a
=== true ? true : false; }
90 function _false_Q(a
) { return a
=== false ? true : false; }
91 function _string_Q(obj
) {
92 return typeof obj
=== 'string' && obj
[0] !== '\u029e';
97 function Symbol(name
) {
101 Symbol
.prototype.toString = function() { return this.value
; }
102 function _symbol(name
) { return new Symbol(name
); }
103 function _symbol_Q(obj
) { return obj
instanceof Symbol
; }
107 function _keyword(obj
) {
108 if (typeof obj
=== 'string' && obj
[0] === '\u029e') {
111 return "\u029e" + obj
;
114 function _keyword_Q(obj
) {
115 return typeof obj
=== 'string' && obj
[0] === '\u029e';
120 function _function(Eval
, Env
, ast
, env
, params
) {
121 var fn = function() {
122 return Eval(ast
, new Env(env
, params
, arguments
));
126 fn
.__gen_env__ = function(args
) { return new Env(env
, params
, args
); };
127 fn
._ismacro_
= false;
130 function _function_Q(obj
) { return typeof obj
== "function"; }
131 Function
.prototype.clone = function() {
133 var temp = function () { return that
.apply(this, arguments
); };
135 temp
[key
] = this[key
];
142 function _list() { return Array
.prototype.slice
.call(arguments
, 0); }
143 function _list_Q(obj
) { return Array
.isArray(obj
) && !obj
.__isvector__
; }
148 var v
= Array
.prototype.slice
.call(arguments
, 0);
149 v
.__isvector__
= true;
152 function _vector_Q(obj
) { return Array
.isArray(obj
) && !!obj
.__isvector__
; }
157 function _hash_map() {
158 if (arguments
.length
% 2 === 1) {
159 throw new Error("Odd number of hash map arguments");
161 var args
= [{}].concat(Array
.prototype.slice
.call(arguments
, 0));
162 return _assoc_BANG
.apply(null, args
);
164 function _hash_map_Q(hm
) {
165 return typeof hm
=== "object" &&
166 !Array
.isArray(hm
) &&
168 !(hm
instanceof Symbol
) &&
169 !(hm
instanceof Atom
);
171 function _assoc_BANG(hm
) {
172 if (arguments
.length
% 2 !== 1) {
173 throw new Error("Odd number of assoc arguments");
175 for (var i
=1; i
<arguments
.length
; i
+=2) {
176 var ktoken
= arguments
[i
],
177 vtoken
= arguments
[i
+1];
178 if (typeof ktoken
!== "string") {
179 throw new Error("expected hash-map key string, got: " + (typeof ktoken
));
185 function _dissoc_BANG(hm
) {
186 for (var i
=1; i
<arguments
.length
; i
++) {
187 var ktoken
= arguments
[i
];
195 function Atom(val
) { this.val
= val
; }
196 function _atom(val
) { return new Atom(val
); }
197 function _atom_Q(atm
) { return atm
instanceof Atom
; }
201 exports
._obj_type
= types
._obj_type
= _obj_type
;
202 exports
._sequential_Q
= types
._sequential_Q
= _sequential_Q
;
203 exports
._equal_Q
= types
._equal_Q
= _equal_Q
;
204 exports
._clone
= types
._clone
= _clone
;
205 exports
._nil_Q
= types
._nil_Q
= _nil_Q
;
206 exports
._true_Q
= types
._true_Q
= _true_Q
;
207 exports
._false_Q
= types
._false_Q
= _false_Q
;
208 exports
._string_Q
= types
._string_Q
= _string_Q
;
209 exports
._symbol
= types
._symbol
= _symbol
;
210 exports
._symbol_Q
= types
._symbol_Q
= _symbol_Q
;
211 exports
._keyword
= types
._keyword
= _keyword
;
212 exports
._keyword_Q
= types
._keyword_Q
= _keyword_Q
;
213 exports
._function
= types
._function
= _function
;
214 exports
._function_Q
= types
._function_Q
= _function_Q
;
215 exports
._list
= types
._list
= _list
;
216 exports
._list_Q
= types
._list_Q
= _list_Q
;
217 exports
._vector
= types
._vector
= _vector
;
218 exports
._vector_Q
= types
._vector_Q
= _vector_Q
;
219 exports
._hash_map
= types
._hash_map
= _hash_map
;
220 exports
._hash_map_Q
= types
._hash_map_Q
= _hash_map_Q
;
221 exports
._assoc_BANG
= types
._assoc_BANG
= _assoc_BANG
;
222 exports
._dissoc_BANG
= types
._dissoc_BANG
= _dissoc_BANG
;
223 exports
._atom
= types
._atom
= _atom
;
224 exports
._atom_Q
= types
._atom_Q
= _atom_Q
;