mirror of
https://github.com/kanaka/mal.git
synced 2024-11-11 00:52:44 +03:00
a05c086f05
- Use Vector class derived from Array - Use Array/Vector.from for initializing/cloning of Array/Vector - Remove most semi-colon line endings - More use of arrow functions - Use Object.assign to copy properties in _malfunc and function cloning. - Remove or inline a bunch of types.js functions that don't really need to be separate functions: _obj_type, _sequential_Q, _symbol, _symbol_Q, _vector, _vector_Q, _hash_map, _hash_map_Q - Simplify dependency list in Makefile - Remove some separate core.js functions by moving them into the core_ns declaration: _nth, keys, vals, with_meta. With node 7, babel is mostly just used for translating imports into CommonJS requires for node.
69 lines
2.2 KiB
JavaScript
69 lines
2.2 KiB
JavaScript
// General functions
|
|
export function _equal_Q (a, b) {
|
|
if (Array.isArray(a) && Array.isArray(b)) {
|
|
if (a.length !== b.length) { return false }
|
|
for (let i=0; i<a.length; i++) {
|
|
if (! _equal_Q(a[i], b[i])) { return false }
|
|
}
|
|
return true
|
|
} else if (a instanceof Map && b instanceof Map) {
|
|
if (a.size !== b.size) { return false }
|
|
for (let k of a.keys()) {
|
|
if (! _equal_Q(a.get(k), b.get(k))) { return false }
|
|
}
|
|
return true
|
|
} else {
|
|
return a === b
|
|
}
|
|
}
|
|
|
|
export function _clone(obj, new_meta) {
|
|
let new_obj = null
|
|
if (_list_Q(obj)) { new_obj = obj.slice(0) }
|
|
else if (obj instanceof Vector) { new_obj = Vector.from(obj.slice(0)) }
|
|
else if (obj instanceof Map) { new_obj = new Map(obj.entries()) }
|
|
else if (obj instanceof Function) { new_obj = obj.clone() }
|
|
else { throw Error("Invalid clone") }
|
|
if (new_meta !== undefined) { new_obj.meta = new_meta }
|
|
return new_obj
|
|
}
|
|
|
|
// Functions
|
|
export function _malfunc(f, ast, env, params, meta=null, ismacro=false) {
|
|
return Object.assign(f, {ast, env, params, meta, ismacro})
|
|
}
|
|
export const _malfunc_Q = f => f.ast ? true : false
|
|
Function.prototype.clone = function() {
|
|
let f = (...a) => this.apply(f, a) // new function instance
|
|
return Object.assign(f, this) // copy original properties
|
|
}
|
|
|
|
|
|
// Keywords
|
|
export const _keyword = obj => _keyword_Q(obj) ? obj : '\u029e' + obj
|
|
export const _keyword_Q = obj => typeof obj === 'string' && obj[0] === '\u029e'
|
|
|
|
// Sequence collections
|
|
export const _list_Q = obj => Array.isArray(obj) && !(obj instanceof Vector)
|
|
|
|
export class Vector extends Array {}
|
|
|
|
export function _assoc_BANG(hm, ...args) {
|
|
if (args.length % 2 === 1) {
|
|
throw new Error('Odd number of assoc arguments')
|
|
}
|
|
// Use iterator/Array.from when it works
|
|
for (let i=0; i<args.length; i+=2) { hm.set(args[i], args[i+1]) }
|
|
return hm
|
|
}
|
|
export function _dissoc_BANG(hm, ...args) {
|
|
for (let i=0; i<args.length; i++) { hm.delete(args[i]) }
|
|
return hm
|
|
}
|
|
|
|
|
|
// Atoms
|
|
export class Atom {
|
|
constructor(val) { this.val = val }
|
|
}
|