Skip to content

Instantly share code, notes, and snippets.

@modernserf
Last active August 29, 2015 14:26
Show Gist options
  • Save modernserf/49a78935216412bcf782 to your computer and use it in GitHub Desktop.
Save modernserf/49a78935216412bcf782 to your computer and use it in GitHub Desktop.
Forth-like stack operations with ES6 iterators
// stackify - take function with (a... -> [b]) signature
// return unused stack with results on top
function S (fn) {
return function* (...args) {
let iter = this;
let ln = fn.length - args.length;
yield* fn.apply(null,args.concat(takeMutable(iter,ln)))
yield* iter
}
}
function takeMutable (iter, count) {
let result = [];
while (count--) {
result.push(iter.next().value);
}
return result;
}
// convert primitive value to stack value
const v = S((a) => [a])
// apply list of stack operations, left to right
function L (...values) {
return function (){
let result = this || [];
for (let val of values) {
if (typeof val === "function") {
result = result::val();
} else {
result = result::v(val);
}
}
return result
}
}
const add = S((a, b) => [a + b]);
const dup = S((a) => [a,a]);
const inc = L(1,add);
function dump () {
console.log([...this])
return this;
}
// JS pipeline syntax
// works with regular iterators
// pushes/pops from _beginning_ of iterator, like linked list
["a","b"]::v("c")::dup()::v(10)::v(20)::add()::dump()
// [30,"c","c","a","b"]
// compose syntax (more forth-like)
L(22,dup,add,inc,10,dump)()
//[10,45]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment