Last active
August 29, 2015 14:26
-
-
Save modernserf/49a78935216412bcf782 to your computer and use it in GitHub Desktop.
Forth-like stack operations with ES6 iterators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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