1
1
mirror of https://github.com/kanaka/mal.git synced 2024-11-11 00:52:44 +03:00
mal/es6/types.js
Joel Martin a05c086f05 ES6: more use of ES6, simplifications, newer babel.
- 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.
2017-02-10 23:02:30 -06:00

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 }
}