diff --git a/ok/convert.js b/ok/convert.js deleted file mode 100644 index 598c004..0000000 --- a/ok/convert.js +++ /dev/null @@ -1,69 +0,0 @@ -//////////////////////////////////// -// -// A companion to oK which bridges -// the gap between k-values and -// native JavaScript types. -// -// John Earnest -// -//////////////////////////////////// - -"use strict"; - -function tok(v) { - if (typeof v == 'number') { - return { t:0, v:v }; - } - if (typeof v == 'string') { - var r = []; - for(var z=0;z k - "dictionary", // 4 : values, k(keys) - "function" , // 5 : body, args, curry, env - "view" , // 6 : value, r, cache, depends->val - "nameref" , // 7 : name, l(index?), r(assignment), global? - "verb" , // 8 : name, l(?), r, curry? - "adverb" , // 9 : name, l(?), verb, r - "return" , // 10 : return (deprecated) - "nil" , // 11 : - "cond" , // 12 : body (list of expressions) - "quote" , // 13 : value (for quoting verbs/etc as a value) -]; - -var NIL = ks(""); -var k0 = k(0, 0); -var k1 = k(0, 1); -var EC = [["\\","\\\\"],["\"","\\\""],["\n","\\n"],["\t","\\t"]]; -var kt = [-9, -10, -11, 0, 99, 102, NaN, NaN, 107, 105, NaN, NaN, NaN]; -var SP = k(1, " ".charCodeAt(0)); -var NA = k(0, NaN); - -function k (t, v) { return { 't':t, 'v':v }; } -function md (x, y) { return { t:4, k:sl(x,y), v:y }; } -function ks (x) { return k(2, x); } -function asVerb(x, y, z) { return { t:8, v:x, l:y, r:z }; } -function kl (x) { return x.length==1 ? x[0] : k(3,x); } -function kf (x) { return match(k(3,[]), x).v || match(k0, x).v; } -function kb (x) { return x ? k1 : k0; } -function s (x) { return x.t == 3 && x.v.every(function(c) { return c.t == 1; }); } -function kmod (x, y) { return x-y*Math.floor(x/y); } -function len (x) { return l(x).v.length; } -function krange(x, f) { var r=[]; for(var z=0;z=len(x)) { throw new Error("length error."); } return x.v[y]; } -function dget (x, y) { var i=find(x.k, y); return (i.v==len(x.k)) ? NA : atx(x.v, i); } -function lset (x, y, z) { if (len(x) <= p(y)) { throw new Error("index error."); } x.v[y.v]=z; } -function dset (x, y, z) { var i=find(x.k, y).v; if(i==len(x.k)) { x.k.v.push(y); } x.v.v[i]=z; } -function lower (x) { return k(1, String.fromCharCode(x.v).toLowerCase().charCodeAt(0)); } -function kmap (x, f) { return k(3, l(x).v.map(f)); } -function kzip (x, y, f) { return kmap(sl(x,y), function(z, i) { return f(z, y.v[i]); }); } -function sl (x, y) { if (len(x) != len(y)) { throw new Error("length error."); } return x; } -function n (x) { return (x.t==0||x.t==1) ? x : ct(x, 0); } -function l (x) { return ct(x, 3); } -function d (x) { return ct(x, 4); } -function a (x) { if (x.t > 2) { throw new Error("domain error."); } return x; } -function na (x) { return x.t === 0 && isNaN(x.v); } - -function stok(x) { return kl(krange(x.length, function(z) { return k(1,x.charCodeAt(z)); }).v); } -function c(x) { return (x.t==3) ? k(x.t, x.v.slice(0)) : (x.t==4) ? md(c(x.k), c(x.v)) : x; } -function ct(n,t) { if (n.t!=t) throw new Error(TN[t]+" expected, found "+TN[n.t]+"."); return n; } -function p(x) { if (n(x).v<0||x.v%1!=0) { throw new Error("positive int expected."); } return x.v; } -function ktos(x, esc) { - if (x.t != 3) { x = enlist(x); } - var h = x.v.some(function(v){ return (v.v<32||v.v>127)&v.v!=9&v.v!=10; }); - if (h) { return "0x"+x.v.map(h2).join(""); } - var r = x.v.map(function(k) { return String.fromCharCode(k.v); }).join(""); - return esc ? '"'+EC.reduce(function(r,p) { return r.split(p[0]).join(p[1]); }, r)+'"' : r; -} - -//////////////////////////////////// -// -// Primitive Verbs -// -//////////////////////////////////// - -function plus (x, y) { return k(0, n(x).v + n(y).v); } -function minus (x, y) { return k(0, n(x).v - n(y).v); } -function times (x, y) { return k(0, n(x).v * n(y).v); } -function divide(x, y) { return k(0, n(x).v / n(y).v); } -function mod (x, y) { return k(0, n(x).v>0 ? kmod(n(y).v, x.v) : Math.floor(n(y).v / -x.v)); } -function max (x, y) { return na(x)?y:na(y)?x:k(0, Math.max(n(x).v, n(y).v)); } -function min (x, y) { return k(0, Math.min(n(x).v, n(y).v)); } -function less (x, y) { return kb(a(x).v < a(y).v); } -function more (x, y) { return kb(a(x).v > a(y).v); } -function equal (x, y) { return kb((x.v == y.v) || (na(x) && na(y))); } -function join (x, y) { return l(y).v.reduce(function(z, y) { return cat(z, cat(x, y)); }); } -function ident (x) { return x; } -function negate (x) { return k(0, -n(x).v); } -function first (x) { return (x.t == 4) ? first(x.v) : (x.t != 3) ? x : len(x) ? x.v[0]:k(3,[]); } -function sqrt (x) { return k(0, Math.sqrt(n(x).v)); } -function keys (x) { return c(d(x).k); } -function rev (x) { return x.t==4?md(rev(x.k),rev(x.v)):x.t==3?k(3,c(l(x)).v.reverse()):x; } -function asc (x) { return grade(-1, x); } -function desc (x) { return grade(1, x); } -function not (x) { return equal(n(x), k0); } -function enlist (x) { return k(3, [x]); } -function isnull (x) { return max(match(x, NIL),match(x,k(11))); } -function count (x) { return k(0, x.t == 4 ? len(x.v) : x.t == 3 ? len(x) : 1); } -function floor (x) { return x.t == 1 ? lower(x) : k(0, Math.floor(n(x).v)); } -function type (x) { return k(0, kt[x.t]); } -function kfmt (x) { var r=stok(format(x, 0, 1)); return r.t == 3 ? r : enlist(r); } -function real (x) { return krange(n(x).v, function() { return k(0, Math.random()); }); } - -function iota(x) { - if (x.t == 4) { return keys(x); } - var i = krange(Math.abs(n(x).v), k.bind(null, 0)); return x.v>=0 ? i : ar(plus)(x, i); -} - -function cat(x, y) { - if (x.t==4&&y.t==4) { x=c(x); kmap(y.k, function(v) { dset(x,v,dget(y,v)); }); return x; }; - return k(3, (x.t==3?x.v:[x]).concat(y.t==3?y.v:[y])); -} - -function keval(x, env) { - if (x.t == 5) { return x.env.d; } - return x.t == 4 ? c(x.v) : x.t == 2 ? env.lookup(x, true) : run(parse(ktos(x)), env); -} - -function dfmt(x, y) { - if ( x.t == 3 && y.t == 3) { return kzip(x, y, dfmt); } - if ( x.t == 3 && y.t != 3) { return kmap(x, function(z) { return dfmt(z, y); }); } - if ((x.t == 2 || !s(y)) && y.t == 3) { return kmap(y, function(z) { return dfmt(x, z); }); } - if (x.t == 2) { return {b: k(0,y.v&1), i: k(0,y.v|0), f: k(0,y.v), c: k(1,y.v)}[x.v]; } - if (y.t == 1) { return y; } var r=c(y); var d=Math.abs(x.v); - while(len(r) < d) { x.v>0 ? r.v.push(SP) : r.v.unshift(SP); } - while(len(r) > d) { x.v>0 ? r.v.pop() : r.v.shift(); } - return r; -} - -function except(x, y) { - y = y.t == 3 ? y : enlist(y); - return k(3, (x.t == 3 ? x : iota(x)).v.filter(function(z) { return na(pfind(y, z)); })); -} - -function ddrop(x, y) { var k = except(d(y).k, x); return md(k, atx(y, k)); } -function drop(x, y) { - if (y.t == 4) { return md(drop(x, y.k), drop(x, y.v)); } - return (y.t != 3 || len(y) < 1) ? y : k(3, n(x).v<0 ? y.v.slice(0,x.v) : y.v.slice(x.v)); -} - -function take(x, y, env) { - if (x.t == 5 || x.t == 8 || x.t == 9) { - var k = where(each(x, y, env), env); var v = atx(y, k); - return y.t == 4 ? md(k, v) : v; - } - if (y.t == 4) { return md(take(x, y.k, env), take(x, y.v, env)); } - if (y.t != 3 || len(y) == 0) { y = enlist(y); } - var s=n(x).v<0?kmod(x.v, len(y)):0; - return krange(Math.abs(x.v), function(x) { return y.v[kmod(x+s, len(y))]; }); -} - -function reshape(x, y) { - if (y.t == 4) { return md(x, atx(y, x)); } - if (y.t != 3) { y = enlist(y); } - var a = first(x); var b = x.v[len(x)-1]; var c = 0; - function rshr(x, y, i) { - return krange(x.v[i].v, function(z) { - return i==len(x)-1 ? y.v[kmod(c++, len(y))] : rshr(x, y, i+1); - }); - } - return na(a) ? (!len(y) ? y : cut(krange(len(y)/b.v, function(z) { return k(0, z*b.v); }), y)) : - na(b) ? cut(krange(a.v, function(z) { return k(0, Math.floor(z*len(y)/a.v)); }), y) : - rshr(l(x), len(y) ? y : enlist(y), 0); -} - -function match(x, y) { - if (x.t != y.t) { return k0; } - if (x.t == 4) { return min(match(x.k, y.k), match(x.v, y.v)); } - if (x.t != 3) { return equal(x, y); } - if (len(x) != len(y)) { return k0; } - return kb(x.v.every(function(x,i) { return match(x, y.v[i]).v; })); -} - -function find(x, y) { y=x.v.findIndex(function(z){return match(z,y).v}); return k(0,y>=0?y:len(x)) } -function pfind(x, y) { y=x.v.findIndex(function(z){return equal(z,y).v}); return y>=0?k(0,y):NA } -function pisnull(x) { return kb(match(x, NIL).v || match(x, k(11)).v || na(x)); } - -function cut(x, y) { - return kzip(x, cat(drop(k1,x),count(y)), function(a, b) { // {x{x@y+!z-y}[y]'1_x,#y} ? - var r=[]; for(var z=p(a);zy.v) throw new Error("length error.");return take(x,asc(real(y)),env); } - return kmap(iota(x), function(x){ return k(0,Math.floor(Math.random()*y.v)); }); -} - -function flip(x, env) { - x=eachright(k(8,"#"), over(k(8,"|"), each(k(8,"#"), x, env), env), x, env); - return krange(len(first(x)), function(z){ - return krange(len(x), function(t){ return x.v[t].v[z]; }); - }); -} - -function grade(dir, x) { - return x.t == 4 ? atx(x.k, grade(dir, x.v)) : k(3, iota(count(x)).v.sort(function(a, b) { - var f = function(i) { var v = x.v[i.v]; return s(v) ? ks(ktos(v)) : v; } - var av = f(a), bv = f(b); return less(av,bv).v ? dir : more(av,bv).v ? -dir : a.v - b.v; - })); -} - -function where(x, env) { - if (x.t == 4) { return atx(x.k, where(x.v, env)); } // {,/(0|x)#'!#x}... - var s = kmap(x.t==3 ?x:enlist(x), function(v,i) { return take(k(0,p(v)), k(0,i), env); }); - return over(asVerb(","), s, env); -} - -function group(x) { - var r={t:4, k:unique(x)}; r.v=kmap(r.k, function(){ return k(3,[]); }); - for(var z=0;z 1) { var i=a+Math.floor((b-a)/2); if (more(x.v[i], y).v) { b=i; } else { a=i; } } - return k(0, a); -} - -function split (x, y) { return (x.t != 1) ? unpack(x, y) : call(splitimpl, k(3, [x,y])); } -function unpack (x, y) { return call(unpackimpl, k(3, [x,y])); } -function pack (x, y) { return (x.t == 1) ? join(x, y) : call(packimpl, k(3, [x,y])); } -function kwindow(x, y) { return call(winimpl, k(3, [x,y])); } -function splice(xyz) { return call(spliceimpl, k(3, xyz)); } -function imat(x) { var i = iota(x); return kmap(i, function(z) { return ar(equal)(z, i); }); } -function odometer(x) { return call(odoimpl, enlist(x)); } - -//////////////////////////////////// -// -// Primitive Adverbs -// -//////////////////////////////////// - -function each(monad, x, env) { - if (x.t == 4) { return md(x.k, each(monad, x.v, env)); } - return kmap(x, function(x) { return applym(monad, x, env); }); -} - -function eachd(dyad, left, right, env) { - if (!env) { return kmap(left, function(x) { return applyd(dyad, x, null, right); }); } - if (left.t==4&&right.t==4) { return md(left.k,eachd(dyad,left.v,atx(right,left.k),env)); } - if (left.t!=3) { return eachright(dyad, left, right, env); } - if (right.t!=3) { return eachleft(dyad, left, right, env); } - return kzip(left, right, function(x, y) { return applyd(dyad, x, y, env); }); -} - -function eachright(dyad, left, list, env) { - return kmap(list, function(x) { return applyd(dyad, left, x, env); }); -} - -function eachleft(dyad, list, right, env) { - return kmap(list, function(x) { return applyd(dyad, x, right, env); }); -} - -function eachprior(dyad, x, env) { - var specials = {"+":k0, "*":k1, "-":k0, "&":first(x), ",":k(3,[]), "%":k1}; - return eachpc(dyad, (dyad.v in specials) ? specials[dyad.v] : NA, x, env); -} - -function eachpc(dyad, x, y, env) { - return kmap(y, function(v) { var t=x; x=v; return applyd(dyad, v, t, env); }); -} - -function over(dyad, x, env) { - var specials = {"+":k0, "*":k1, "|":k(0,-1/0), "&":k(0,1/0)}; - if (x.t == 3 && len(x) < 1 && dyad.v in specials) { return specials[dyad.v]; } - if (x.t == 3 && len(x) == 1 && dyad.v == ",") { return first(x).t != 3 ? x : first(x); } - if (x.t != 3 || len(x) < 1) { return x; } - return overd(dyad, first(x), drop(k1,x), env); -} - -function overd(dyad, x, y, env) { - return y.v.reduce(function(x, y) { return applyd(dyad, x, y, env); }, x); -} - -function eacha(func, args, env) { - var x = args[0]; var y = flip(k(3, args.slice(1)), env); - if (x.t != 3) { return kmap(y, function(y) { return call(func, cat(x, y), env); }); } - return kzip(x, y, function(x, y) { return call(func, cat(x, y), env); }); -} -function overa(func, args, env) { - var x = args[0]; var y = flip(k(3, args.slice(1)), env); - return y.v.reduce(function(x, y) { return call(func, cat(enlist(x), y), env); }, x); -} -function scana(func, args, env) { - var x = args[0]; var y = flip(k(3, args.slice(1)), env); - return cat(x, kmap(y, function(y) { return x = call(func, cat(enlist(x), y), env); })); -} - -function fixed(monad, x, env) { - var r=x, p=x; - do { r=applym(monad, p=r, env); } while(!match(p, r).v && !match(r, x).v); return p; -} - -function fixedwhile(monad, x, y, env) { - if (x.t == 0) { for(var z=0;z" : [desc, desc, ad(more), ad(more), ad(more), ad(more), null, null ], - "=" : [imat, group, ad(equal), ad(equal), ad(equal), ad(equal), null, null ], - "~" : [am(not), am(not), match, match, match, match, null, null ], - "," : [enlist, enlist, cat, cat, cat, cat, null, null ], - "^" : [pisnull, am(pisnull),except, except, except, except, null, null ], - "#" : [count, count, take, reshape, take, reshape, null, null ], - "_" : [am(floor), am(floor), drop, ddrop, drop, cut, null, null ], - "$" : [kfmt, am(kfmt), dfmt, dfmt, dfmt, dfmt, null, null ], - "?" : [real, unique, rnd, pfind, rnd, ar(pfind), splice, null ], - "@" : [type, type, atx, atx, atx, atx, amend4, amend4], - "." : [keval, keval, call, call, call, call, dmend4, dmend4], - "'" : [null, null, null, bin, null, ar(bin), null, null ], - "/" : [null, null, null, null, pack, pack, null, null ], - "\\": [null, null, null, unpack, split, null, null, null ], - "':": [null, null, null, null, kwindow, null, null, null ], -}; - -function applyverb(node, args, env) { - if (node.curry) { - var a=[]; var i=0; for(var z=0;z 2) ? r(args, env) : left ? r(left, right, env) : r(right, env) -} - -function valence(node, env) { - if (node.t == 5) { - return (node.curry||[]).reduce(function(x,v) { return x-!isnull(v).v; }, node.args.length); - } - if (node.t == 7) { return valence(env.lookup(ks(node.v))); } - if (node.t == 9 && node.v == "'") { return valence(node.verb, env); } - if (node.t == 9) { return 1; } - if (node.t != 8) { return 0; } - if (node.forcemonad) { return 1; } - if (node.v in natives) { return 1; } - return (node.sticky && (node.sticky.t==9 || node.sticky.forcemonad || node.sticky.l)) ? 1 : 2; -} - -var adverbs = { - // mv/nv dv l-mv l-dv 3+v - "':" : [null, eachprior, null, eachpc, null ], - "'" : [each, eachd, eachd, eachd, eacha], - "/:" : [null, null, eachright, eachright, null ], - "\\:" : [null, null, eachleft, eachleft, null ], - "/" : [fixed, over, fixedwhile, overd, overa], - "\\" : [scanfixed, scan, scanwhile, scand, scana], -}; - -function applyadverb(node, verb, args, env) { - if (verb.t == 7) { verb = run(verb, env); } - var r = null; var v = valence(verb, env); - if (v > 2) { return adverbs[node.v][4](verb, args, env); } - if (v == 0 && verb.t != 5) { return applyverb(k(8,node.v), [verb, args[1]], env); } - if (v == 0 && verb.t == 5) { v = 1; } - if (v == 2 && !args[1]) { args = [null, args[0]]; } - if (v == 1 && !args[0]) { r = adverbs[node.v][0]; } - if (v == 2 && !args[0]) { r = adverbs[node.v][1]; } - if (v == 1 && args[0]) { r = adverbs[node.v][2]; } - if (v == 2 && args[0]) { r = adverbs[node.v][3]; } - if (!r) { throw new Error("invalid arguments to "+node.v+" ["+ - (args[0]?format(args[0])+" ":"")+" "+format(verb)+" (valence "+v+"), "+format(args[1])+"]"); - } - return args[0] ? r(verb, args[0], args[1], env) : r(verb, args[1], env); -} - -function Environment(pred) { - this.p = pred; this.d = md(k(3,[]), k(3,[])); - this.put = function(n, g, v) { - if (typeof n == "string") { n = ks(n); } - if (g && this.p) { this.p.put(n, g, v); } else { dset(this.d, n, v); } - }; - this.contains = function(x) { return find(this.d.k, x).v != len(this.d.k); } - this.lookup = function(n, g) { - if (g && this.p) { return this.p.lookup(n, g); } - if (!this.contains(n)) { - if (!this.p) { throw new Error("the name '"+n.v+"' has not been defined."); } - return this.p.lookup(n); - } - var view = dget(this.d, n); - if (view.t == 6) { - var dirty = view.cache == 0, env = this; - Object.keys(view.depends).forEach(function(z) { - var n = (z == view.v) ? view.cache : env.lookup(ks(z)), o = view.depends[z]; - if (!o || !match(n,o).v) { dirty=1; view.depends[z]=n; } - }) - if (dirty) { view.cache = run(view.r, this); } return view.cache; - } - return view; - }; -} - -function atx(x, y, env) { - return x.t == 2 ? atx(env.lookup(x), y, env) : y.t == 11 ? x : - x.t == 3 && y.t == 4 ? md(y.k, atx(x, y.v, env)) : - x.t == 8 || x.t == 9 ? applym(x, y, env) : - (x.t == 3 || x.t == 4) && y.t == 3 ? kmap(y, function(z) { return atx(x, z); }) : - x.t == 3 ? (y.t > 1 || y.v < 0 || y.v >= len(x) || y.v%1 != 0) ? NA : x.v[y.v] : - x.t == 4 ? dget(x, y) : call(x, enlist(y), env) -} - -function atdepth(x, y, i, env) { - if (i >= len(y)) { return x; }; var c = y.v[i]; var k = atx(x, c, env); - return (c.t != 11 && c.t != 3) ? atdepth(k, y, i+1, env) : - kmap(k, function(t) { return atdepth(t, y, i+1, env) }) -} - -function call(x, y, env) { - if (x.sticky) { return (valence(x.sticky, env)==1?applym:applyd)(x, y.v[0], y.v[1], env); } - if (x.t == 2) { return call(env.lookup(x), y, env); } - if (x.t == 3 || x.t == 4) { return y.t == 3 ? atdepth(x, y, 0, env) : atx(x, y, env); } - if (x.t == 8) { return applyverb(x, y.t == 3 ? y.v : [y], env); } - if (x.t == 9) { return applyadverb(x, run(x.verb, env), y.v, env); } - if (x.t != 5) { throw new Error("function or list expected, found " + TN[x.t]+'.'); } - if (y.t == 4) { var e=new Environment(null); e.d=y; x.env=e; return x; } - if (y.t != 3) { y = enlist(y); } - var environment = new Environment(x.env); var curry = x.curry?x.curry.concat([]):[]; - if (x.args.length != 0 || len(y) != 1 || !isnull(y.v[0]).v) { - var all=true; var i=0; for(var z=0;z= len(y)) { all=false; break; } - if (y.v[i] == null || isnull(y.v[i]).v) { all=false; } - curry[z]=y.v[i++]; - } - if (!all) { return { t:5, v:x.v, args:x.args, env:x.env, curry:curry }; } - if (i < len(y) && x.args.length != 0) { throw new Error("valence error."); } - for(var z=0;z=~,^#_$?@.]/; -var ASSIGN = /^[+\-*%!&|<>=~,^#_$?@.]:/; -var IOVERB = /^\d:/; -var ADVERB = /^['\\\/]:?/; -var SEMI = /^;/; -var COLON = /^:/; -var VIEW = /^::/; -var COND = /^\$\[/; -var DICT = /^\[[a-z]+:/i; -var OPEN_B = /^\[/; -var OPEN_P = /^\(/; -var OPEN_C = /^{/; -var CLOSE_B = /^\]/; -var CLOSE_P = /^\)/; -var CLOSE_C = /^}/; - -var des = {}; -des[NUMBER ]="number";des[NAME ]="name" ;des[SYMBOL ]="symbol";des[STRING]="string"; -des[VERB ]="verb" ;des[IOVERB ]="IO verb";des[ADVERB ]="adverb";des[SEMI ]="';'"; -des[COLON ]="':'" ;des[VIEW ]="view" ;des[COND ]="'$['" ; -des[OPEN_B ]="'['" ;des[OPEN_P ]="'('" ;des[OPEN_C ]="'{'" ;des[ASSIGN]="assignment"; -des[CLOSE_B]="']'" ;des[CLOSE_P]="')'" ;des[CLOSE_C]="'}'"; - -var text = ""; -var funcdepth = 0; -function begin(str) { - str = str.replace(/("(?:[^"\\\n]|\\.)*")|(\s\/.*)|([a-z\d\]\)]-\.?\d)/gi, function(_, x, y, z) { - // preserve a string (x), remove a comment (y), disambiguate a minus sign (z) - return x ? x : y ? "" : z.replace('-', '- ') - }) - text = str.trim().replace(/\n/g, ";"); funcdepth = 0; -} -function done() { return text.length < 1; } -function at(regex) { return regex.test(text); } -function matches(regex) { return at(regex) ? expect(regex) : false; } -function expect(regex) { - var found = regex.exec(text); - if (regex == OPEN_C) { funcdepth++; } if (regex == CLOSE_C) { funcdepth--; } - if (found == null) { throw new Error("parse error. "+des[regex]+" expected."); } - text = text.substring(found[0].length).trim(); return found[0]; -} - -//////////////////////////////////// -// -// Parser -// -//////////////////////////////////// - -function findNames(node, names) { - if (node == null) { return names; } - if (node instanceof Array) { node.forEach(function(v) { findNames(v, names); }); return names; } - if (node.t == 7) { names[node.v] = 0; } - if (node.t != 5) { findNames(node.v, names); } - return findNames([node.l, node.r, node.verb, node.curry], names); -} - -function atNoun() { - return !done()&&at(NUMBER)||at(NAME)||at(SYMBOL)||at(STRING)||at(COND)||at(OPEN_P)||at(OPEN_C); -} - -function indexedassign(node, indexer) { - var op = { t:5, args:["x","y"], v:[{ t:7, v:"y" }] }; // {y} - var gl = matches(COLON); - var ex = parseEx(parseNoun()); - //t[x]::z -> ..[`t;x;{y};z] t[x]:z -> t:.[t;x;{y};z] - if (!gl) { node.r = { t:8, v:".", curry:[ k(7,node.v), kl(indexer), op, ex] }; return node; } - return { t:8, v:".", r:{ t:8, v:".", curry:[ks(node.v), kl(indexer), op, ex] }}; -} - -function compoundassign(node, indexer) { - if (!at(ASSIGN)) { return node; } - var op = expect(ASSIGN).slice(0,1); var gl = matches(COLON); var ex = parseEx(parseNoun()); - if (!indexer) { - // t+::z -> t::(.`t)+z - var v = gl ? asVerb(".", null, ks(node.v)) : node; - return { t:node.t, v:node.v, global:gl, r:asVerb(op, v, ex) }; - } - // t[x]+::z -> ..[`t;x;+:;z] t[x]+:z -> t:.[t;x;{y};z] - if (!gl) { node.r={ t:8, v:".", curry:[ k(7,node.v),kl(indexer),asVerb(op),ex] }; return node; } - return asVerb(".", null, { t:8, v:".", curry:[ks(node.v), indexer, asVerb(op), ex] }); -} - -function applycallright(node) { - while (matches(OPEN_B)) { - var args = parseList(CLOSE_B); node = asVerb(".", node, k(3, args.length ? args : [NIL])); - } return node; -} - -function applyindexright(node) { - if (node.sticky && at(VERB)) { - var x = parseNoun(); x.l = node; x.r = parseEx(parseNoun()); return x; - } - while (matches(OPEN_B)) { node = asVerb(".", node, k(3, parseList(CLOSE_B))); } - return node; -} - -function findSticky(root) { - var n = root; if (n == null || (n.t == 9 && n.r == null)) { return; } - while(n.t == 8 && !n.curry || n.t == 9) { - if (n.r == null) { root.sticky = n; return; } n = n.r; - } -} - -function parseList(terminal, cull) { - var r=[]; do { - if (terminal && at(terminal)) { break; } - while(matches(SEMI)) { if (!cull) { r.push(k(11)); } } - var e = parseEx(parseNoun()); findSticky(e); - if (e != null) { r.push(e); } - else if (!cull) { r.push(k(11)); } - } while(matches(SEMI)); if (terminal) { expect(terminal); } return r; -} - -function parseNoun() { - if (matches(COLON)) { return { t:5, args:["x","y"], v:[{ t:7, v:"y" }] }; } // {y} - if (at(IOVERB)) { return k(8, expect(IOVERB)); } - if (at(BOOL)) { - var n = expect(BOOL); var r=[]; - for(var z=0;z@x;!x;x]}"), env); - run(parse("in:{~^y?x}"), env); - return env; -} - -var packimpl = parse("{+/y*|*\\1,|1_(#y)#x}")[0]; -var unpackimpl = parse("{(1_r,,y)-x*r:|y(_%)\\|x}")[0]; -var spliceimpl = parse("{,/(*x;$[99<@z;z x 1;z];*|x:(0,y)_x)}")[0]; -var winimpl = parse("{$[0>x;3':0,y,0;y(!0|1+(#y)-x)+\\:!x]}")[0]; -var odoimpl = parse("{+x\\'!*/x}")[0]; -var splitimpl = parse("{1_'(&x=y)_y:x,y}")[0]; - -// export the public interface: -function setIO(symbol, slot, func) { - if (!(symbol in verbs)) { verbs[symbol]=[null,null,null,null,null,null]; } - verbs[symbol][slot] = func; -} - -this.version = "0.1"; -this.parse = parse; -this.format = format; -this.run = run; -this.Environment = Environment; -this.baseEnv = baseEnv; -this.setIO = setIO; -// stolen from iKe -var katan2 = function(x, y) { return k(0, Math.atan2(n(x).v, n(y).v)); } -var kpow = function(x, y) { return k(0, Math.pow (n(x).v, n(y).v)); } -verbs["atan2"] = [null, null, ad(katan2), ad(katan2), ad(katan2), ad(katan2), null, null]; -verbs["pow" ] = [null, null, ad(kpow) , ad(kpow) , ad(kpow) , ad(kpow) , null, null]; -// stolen from convert.js -function trampoline(env, name, args, body) { - // construct a function-wrapper trampoline for a pseudonative. - // this permits dyadic/triadic extension functions to be properly curryable. - var arguse = []; for(var z=0; z 4 || Math.max.apply(null, spl.map(x => x.length)) > 400 ) { + // we need to pastebin it + // make dir + if (!fs.existsSync(happydir)) { fs.mkdirSync(happydir); } + // make fname + var fn = crypto.createHash('md5').update(output).digest('hex'); + fn = fn.slice(0,10) + '.txt'; + // write fname + fs.writeFileSync(happydir + '/' + fn, output); + output = 'https://zgrep.org/ok/' + fn + '\n' + } + // output checking code goes here. + process.stdout.write(output); + } + } +}); diff --git a/ok/oK.js b/ok/oK.js deleted file mode 100644 index 50e4076..0000000 --- a/ok/oK.js +++ /dev/null @@ -1,939 +0,0 @@ -//////////////////////////////////// -// -// A small(ish) implementation -// of the K programming language. -// -// John Earnest -// -//////////////////////////////////// - -"use strict"; - -var TN = [ - "number" , // 0 : value - "char" , // 1 : value - "symbol" , // 2 : value - "list" , // 3 : array -> k - "dictionary", // 4 : values, k(keys) - "function" , // 5 : body, args, curry, env - "view" , // 6 : value, r, cache, depends->val - "nameref" , // 7 : name, l(index?), r(assignment), global? - "verb" , // 8 : name, l(?), r, curry? - "adverb" , // 9 : name, l(?), verb, r - "return" , // 10 : return (deprecated) - "nil" , // 11 : - "cond" , // 12 : body (list of expressions) - "quote" , // 13 : value (for quoting verbs/etc as a value) -]; - -var NIL = ks(""); -var k0 = k(0, 0); -var k1 = k(0, 1); -var EC = [["\\","\\\\"],["\"","\\\""],["\n","\\n"],["\t","\\t"]]; -var kt = [-9, -10, -11, 0, 99, 102, NaN, NaN, 107, 105, NaN, NaN, NaN]; -var SP = k(1, " ".charCodeAt(0)); -var NA = k(0, NaN); - -function k (t, v) { return { 't':t, 'v':v }; } -function md (x, y) { return { t:4, k:sl(x,y), v:y }; } -function ks (x) { return k(2, x); } -function asVerb(x, y, z) { return { t:8, v:x, l:y, r:z }; } -function kl (x) { return x.length==1 ? x[0] : k(3,x); } -function kf (x) { return match(k(3,[]), x).v || match(k0, x).v; } -function kb (x) { return x ? k1 : k0; } -function s (x) { return x.t == 3 && x.v.every(function(c) { return c.t == 1; }); } -function kmod (x, y) { return x-y*Math.floor(x/y); } -function len (x) { return l(x).v.length; } -function krange(x, f) { var r=[]; for(var z=0;z=len(x)) { throw new Error("length error."); } return x.v[y]; } -function dget (x, y) { var i=find(x.k, y); return (i.v==len(x.k)) ? NA : atx(x.v, i); } -function lset (x, y, z) { if (len(x) <= p(y)) { throw new Error("index error."); } x.v[y.v]=z; } -function dset (x, y, z) { var i=find(x.k, y).v; if(i==len(x.k)) { x.k.v.push(y); } x.v.v[i]=z; } -function lower (x) { return k(1, String.fromCharCode(x.v).toLowerCase().charCodeAt(0)); } -function kmap (x, f) { return k(3, l(x).v.map(f)); } -function kzip (x, y, f) { return kmap(sl(x,y), function(z, i) { return f(z, y.v[i]); }); } -function sl (x, y) { if (len(x) != len(y)) { throw new Error("length error."); } return x; } -function n (x) { return (x.t==0||x.t==1) ? x : ct(x, 0); } -function l (x) { return ct(x, 3); } -function d (x) { return ct(x, 4); } -function a (x) { if (x.t > 2) { throw new Error("domain error."); } return x; } -function na (x) { return x.t === 0 && isNaN(x.v); } - -function stok(x) { return kl(krange(x.length, function(z) { return k(1,x.charCodeAt(z)); }).v); } -function c(x) { return (x.t==3) ? k(x.t, x.v.slice(0)) : (x.t==4) ? md(c(x.k), c(x.v)) : x; } -function ct(n,t) { if (n.t!=t) throw new Error(TN[t]+" expected, found "+TN[n.t]+"."); return n; } -function p(x) { if (n(x).v<0||x.v%1!=0) { throw new Error("positive int expected."); } return x.v; } -function ktos(x, esc) { - if (x.t != 3) { x = enlist(x); } - var h = x.v.some(function(v){ return (v.v<32||v.v>127)&v.v!=9&v.v!=10; }); - if (h) { return "0x"+x.v.map(h2).join(""); } - var r = x.v.map(function(k) { return String.fromCharCode(k.v); }).join(""); - return esc ? '"'+EC.reduce(function(r,p) { return r.split(p[0]).join(p[1]); }, r)+'"' : r; -} - -//////////////////////////////////// -// -// Primitive Verbs -// -//////////////////////////////////// - -function plus (x, y) { return k(0, n(x).v + n(y).v); } -function minus (x, y) { return k(0, n(x).v - n(y).v); } -function times (x, y) { return k(0, n(x).v * n(y).v); } -function divide(x, y) { return k(0, n(x).v / n(y).v); } -function mod (x, y) { return k(0, n(x).v>0 ? kmod(n(y).v, x.v) : Math.floor(n(y).v / -x.v)); } -function max (x, y) { return na(x)?y:na(y)?x:k(0, Math.max(n(x).v, n(y).v)); } -function min (x, y) { return k(0, Math.min(n(x).v, n(y).v)); } -function less (x, y) { return kb(a(x).v < a(y).v); } -function more (x, y) { return kb(a(x).v > a(y).v); } -function equal (x, y) { return kb((x.v == y.v) || (na(x) && na(y))); } -function join (x, y) { return l(y).v.reduce(function(z, y) { return cat(z, cat(x, y)); }); } -function ident (x) { return x; } -function negate (x) { return k(0, -n(x).v); } -function first (x) { return (x.t == 4) ? first(x.v) : (x.t != 3) ? x : len(x) ? x.v[0]:k(3,[]); } -function sqrt (x) { return k(0, Math.sqrt(n(x).v)); } -function keys (x) { return c(d(x).k); } -function rev (x) { return x.t==4?md(rev(x.k),rev(x.v)):x.t==3?k(3,c(l(x)).v.reverse()):x; } -function asc (x) { return grade(-1, x); } -function desc (x) { return grade(1, x); } -function not (x) { return equal(n(x), k0); } -function enlist (x) { return k(3, [x]); } -function isnull (x) { return max(match(x, NIL),match(x,k(11))); } -function count (x) { return k(0, x.t == 4 ? len(x.v) : x.t == 3 ? len(x) : 1); } -function floor (x) { return x.t == 1 ? lower(x) : k(0, Math.floor(n(x).v)); } -function type (x) { return k(0, kt[x.t]); } -function kfmt (x) { var r=stok(format(x, 0, 1)); return r.t == 3 ? r : enlist(r); } -function real (x) { return krange(n(x).v, function() { return k(0, Math.random()); }); } - -function iota(x) { - if (x.t == 4) { return keys(x); } - var i = krange(Math.abs(n(x).v), k.bind(null, 0)); return x.v>=0 ? i : ar(plus)(x, i); -} - -function cat(x, y) { - if (x.t==4&&y.t==4) { x=c(x); kmap(y.k, function(v) { dset(x,v,dget(y,v)); }); return x; }; - return k(3, (x.t==3?x.v:[x]).concat(y.t==3?y.v:[y])); -} - -function keval(x, env) { - if (x.t == 5) { return x.env.d; } - return x.t == 4 ? c(x.v) : x.t == 2 ? env.lookup(x, true) : run(parse(ktos(x)), env); -} - -function dfmt(x, y) { - if ( x.t == 3 && y.t == 3) { return kzip(x, y, dfmt); } - if ( x.t == 3 && y.t != 3) { return kmap(x, function(z) { return dfmt(z, y); }); } - if ((x.t == 2 || !s(y)) && y.t == 3) { return kmap(y, function(z) { return dfmt(x, z); }); } - if (x.t == 2) { return {b: k(0,y.v&1), i: k(0,y.v|0), f: k(0,y.v), c: k(1,y.v)}[x.v]; } - if (y.t == 1) { return y; } var r=c(y); var d=Math.abs(x.v); - while(len(r) < d) { x.v>0 ? r.v.push(SP) : r.v.unshift(SP); } - while(len(r) > d) { x.v>0 ? r.v.pop() : r.v.shift(); } - return r; -} - -function except(x, y) { - y = y.t == 3 ? y : enlist(y); - return k(3, (x.t == 3 ? x : iota(x)).v.filter(function(z) { return na(pfind(y, z)); })); -} - -function ddrop(x, y) { var k = except(d(y).k, x); return md(k, atx(y, k)); } -function drop(x, y) { - if (y.t == 4) { return md(drop(x, y.k), drop(x, y.v)); } - return (y.t != 3 || len(y) < 1) ? y : k(3, n(x).v<0 ? y.v.slice(0,x.v) : y.v.slice(x.v)); -} - -function take(x, y, env) { - if (x.t == 5 || x.t == 8 || x.t == 9) { - var k = where(each(x, y, env), env); var v = atx(y, k); - return y.t == 4 ? md(k, v) : v; - } - if (y.t == 4) { return md(take(x, y.k, env), take(x, y.v, env)); } - if (y.t != 3 || len(y) == 0) { y = enlist(y); } - var s=n(x).v<0?kmod(x.v, len(y)):0; - return krange(Math.abs(x.v), function(x) { return y.v[kmod(x+s, len(y))]; }); -} - -function reshape(x, y) { - if (y.t == 4) { return md(x, atx(y, x)); } - if (y.t != 3) { y = enlist(y); } - var a = first(x); var b = x.v[len(x)-1]; var c = 0; - function rshr(x, y, i) { - return krange(x.v[i].v, function(z) { - return i==len(x)-1 ? y.v[kmod(c++, len(y))] : rshr(x, y, i+1); - }); - } - return na(a) ? (!len(y) ? y : cut(krange(len(y)/b.v, function(z) { return k(0, z*b.v); }), y)) : - na(b) ? cut(krange(a.v, function(z) { return k(0, Math.floor(z*len(y)/a.v)); }), y) : - rshr(l(x), len(y) ? y : enlist(y), 0); -} - -function match(x, y) { - if (x.t != y.t) { return k0; } - if (x.t == 4) { return min(match(x.k, y.k), match(x.v, y.v)); } - if (x.t != 3) { return equal(x, y); } - if (len(x) != len(y)) { return k0; } - return kb(x.v.every(function(x,i) { return match(x, y.v[i]).v; })); -} - -function find(x, y) { y=x.v.findIndex(function(z){return match(z,y).v}); return k(0,y>=0?y:len(x)) } -function pfind(x, y) { y=x.v.findIndex(function(z){return equal(z,y).v}); return y>=0?k(0,y):NA } -function pisnull(x) { return kb(match(x, NIL).v || match(x, k(11)).v || na(x)); } - -function cut(x, y) { - return kzip(x, cat(drop(k1,x),count(y)), function(a, b) { // {x{x@y+!z-y}[y]'1_x,#y} ? - var r=[]; for(var z=p(a);zy.v) throw new Error("length error.");return take(x,asc(real(y)),env); } - return kmap(iota(x), function(x){ return k(0,Math.floor(Math.random()*y.v)); }); -} - -function flip(x, env) { - x=eachright(k(8,"#"), over(k(8,"|"), each(k(8,"#"), x, env), env), x, env); - return krange(len(first(x)), function(z){ - return krange(len(x), function(t){ return x.v[t].v[z]; }); - }); -} - -function grade(dir, x) { - return x.t == 4 ? atx(x.k, grade(dir, x.v)) : k(3, iota(count(x)).v.sort(function(a, b) { - var f = function(i) { var v = x.v[i.v]; return s(v) ? ks(ktos(v)) : v; } - var av = f(a), bv = f(b); return less(av,bv).v ? dir : more(av,bv).v ? -dir : a.v - b.v; - })); -} - -function where(x, env) { - if (x.t == 4) { return atx(x.k, where(x.v, env)); } // {,/(0|x)#'!#x}... - var s = kmap(x.t==3 ?x:enlist(x), function(v,i) { return take(k(0,p(v)), k(0,i), env); }); - return over(asVerb(","), s, env); -} - -function group(x) { - var r={t:4, k:unique(x)}; r.v=kmap(r.k, function(){ return k(3,[]); }); - for(var z=0;z 1) { var i=a+Math.floor((b-a)/2); if (more(x.v[i], y).v) { b=i; } else { a=i; } } - return k(0, a); -} - -function split (x, y) { return (x.t != 1) ? unpack(x, y) : call(splitimpl, k(3, [x,y])); } -function unpack (x, y) { return call(unpackimpl, k(3, [x,y])); } -function pack (x, y) { return (x.t == 1) ? join(x, y) : call(packimpl, k(3, [x,y])); } -function kwindow(x, y) { return call(winimpl, k(3, [x,y])); } -function splice(xyz) { return call(spliceimpl, k(3, xyz)); } -function imat(x) { var i = iota(x); return kmap(i, function(z) { return ar(equal)(z, i); }); } -function odometer(x) { return call(odoimpl, enlist(x)); } - -//////////////////////////////////// -// -// Primitive Adverbs -// -//////////////////////////////////// - -function each(monad, x, env) { - if (x.t == 4) { return md(x.k, each(monad, x.v, env)); } - return kmap(x, function(x) { return applym(monad, x, env); }); -} - -function eachd(dyad, left, right, env) { - if (!env) { return kmap(left, function(x) { return applyd(dyad, x, null, right); }); } - if (left.t==4&&right.t==4) { return md(left.k,eachd(dyad,left.v,atx(right,left.k),env)); } - if (left.t!=3) { return eachright(dyad, left, right, env); } - if (right.t!=3) { return eachleft(dyad, left, right, env); } - return kzip(left, right, function(x, y) { return applyd(dyad, x, y, env); }); -} - -function eachright(dyad, left, list, env) { - return kmap(list, function(x) { return applyd(dyad, left, x, env); }); -} - -function eachleft(dyad, list, right, env) { - return kmap(list, function(x) { return applyd(dyad, x, right, env); }); -} - -function eachprior(dyad, x, env) { - var specials = {"+":k0, "*":k1, "-":k0, "&":first(x), ",":k(3,[]), "%":k1}; - return eachpc(dyad, (dyad.v in specials) ? specials[dyad.v] : NA, x, env); -} - -function eachpc(dyad, x, y, env) { - return kmap(y, function(v) { var t=x; x=v; return applyd(dyad, v, t, env); }); -} - -function over(dyad, x, env) { - var specials = {"+":k0, "*":k1, "|":k(0,-1/0), "&":k(0,1/0)}; - if (x.t == 3 && len(x) < 1 && dyad.v in specials) { return specials[dyad.v]; } - if (x.t == 3 && len(x) == 1 && dyad.v == ",") { return first(x).t != 3 ? x : first(x); } - if (x.t != 3 || len(x) < 1) { return x; } - return overd(dyad, first(x), drop(k1,x), env); -} - -function overd(dyad, x, y, env) { - return y.v.reduce(function(x, y) { return applyd(dyad, x, y, env); }, x); -} - -function eacha(func, args, env) { - var x = args[0]; var y = flip(k(3, args.slice(1)), env); - if (x.t != 3) { return kmap(y, function(y) { return call(func, cat(x, y), env); }); } - return kzip(x, y, function(x, y) { return call(func, cat(x, y), env); }); -} -function overa(func, args, env) { - var x = args[0]; var y = flip(k(3, args.slice(1)), env); - return y.v.reduce(function(x, y) { return call(func, cat(enlist(x), y), env); }, x); -} -function scana(func, args, env) { - var x = args[0]; var y = flip(k(3, args.slice(1)), env); - return cat(x, kmap(y, function(y) { return x = call(func, cat(enlist(x), y), env); })); -} - -function fixed(monad, x, env) { - var r=x, p=x; - do { r=applym(monad, p=r, env); } while(!match(p, r).v && !match(r, x).v); return p; -} - -function fixedwhile(monad, x, y, env) { - if (x.t == 0) { for(var z=0;z" : [desc, desc, ad(more), ad(more), ad(more), ad(more), null, null ], - "=" : [imat, group, ad(equal), ad(equal), ad(equal), ad(equal), null, null ], - "~" : [am(not), am(not), match, match, match, match, null, null ], - "," : [enlist, enlist, cat, cat, cat, cat, null, null ], - "^" : [pisnull, am(pisnull),except, except, except, except, null, null ], - "#" : [count, count, take, reshape, take, reshape, null, null ], - "_" : [am(floor), am(floor), drop, ddrop, drop, cut, null, null ], - "$" : [kfmt, am(kfmt), dfmt, dfmt, dfmt, dfmt, null, null ], - "?" : [real, unique, rnd, pfind, rnd, ar(pfind), splice, null ], - "@" : [type, type, atx, atx, atx, atx, amend4, amend4], - "." : [keval, keval, call, call, call, call, dmend4, dmend4], - "'" : [null, null, null, bin, null, ar(bin), null, null ], - "/" : [null, null, null, null, pack, pack, null, null ], - "\\": [null, null, null, unpack, split, null, null, null ], - "':": [null, null, null, null, kwindow, null, null, null ], -}; - -function applyverb(node, args, env) { - if (node.curry) { - var a=[]; var i=0; for(var z=0;z 2) ? r(args, env) : left ? r(left, right, env) : r(right, env) -} - -function valence(node, env) { - if (node.t == 5) { - return (node.curry||[]).reduce(function(x,v) { return x-!isnull(v).v; }, node.args.length); - } - if (node.t == 7) { return valence(env.lookup(ks(node.v))); } - if (node.t == 9 && node.v == "'") { return valence(node.verb, env); } - if (node.t == 9) { return 1; } - if (node.t != 8) { return 0; } - if (node.forcemonad) { return 1; } - if (node.v in natives) { return 1; } - return (node.sticky && (node.sticky.t==9 || node.sticky.forcemonad || node.sticky.l)) ? 1 : 2; -} - -var adverbs = { - // mv/nv dv l-mv l-dv 3+v - "':" : [null, eachprior, null, eachpc, null ], - "'" : [each, eachd, eachd, eachd, eacha], - "/:" : [null, null, eachright, eachright, null ], - "\\:" : [null, null, eachleft, eachleft, null ], - "/" : [fixed, over, fixedwhile, overd, overa], - "\\" : [scanfixed, scan, scanwhile, scand, scana], -}; - -function applyadverb(node, verb, args, env) { - if (verb.t == 7) { verb = run(verb, env); } - var r = null; var v = valence(verb, env); - if (v > 2) { return adverbs[node.v][4](verb, args, env); } - if (v == 0 && verb.t != 5) { return applyverb(k(8,node.v), [verb, args[1]], env); } - if (v == 0 && verb.t == 5) { v = 1; } - if (v == 2 && !args[1]) { args = [null, args[0]]; } - if (v == 1 && !args[0]) { r = adverbs[node.v][0]; } - if (v == 2 && !args[0]) { r = adverbs[node.v][1]; } - if (v == 1 && args[0]) { r = adverbs[node.v][2]; } - if (v == 2 && args[0]) { r = adverbs[node.v][3]; } - if (!r) { throw new Error("invalid arguments to "+node.v+" ["+ - (args[0]?format(args[0])+" ":"")+" "+format(verb)+" (valence "+v+"), "+format(args[1])+"]"); - } - return args[0] ? r(verb, args[0], args[1], env) : r(verb, args[1], env); -} - -function Environment(pred) { - this.p = pred; this.d = md(k(3,[]), k(3,[])); - this.put = function(n, g, v) { - if (typeof n == "string") { n = ks(n); } - if (g && this.p) { this.p.put(n, g, v); } else { dset(this.d, n, v); } - }; - this.contains = function(x) { return find(this.d.k, x).v != len(this.d.k); } - this.lookup = function(n, g) { - if (g && this.p) { return this.p.lookup(n, g); } - if (!this.contains(n)) { - if (!this.p) { throw new Error("the name '"+n.v+"' has not been defined."); } - return this.p.lookup(n); - } - var view = dget(this.d, n); - if (view.t == 6) { - var dirty = view.cache == 0, env = this; - Object.keys(view.depends).forEach(function(z) { - var n = (z == view.v) ? view.cache : env.lookup(ks(z)), o = view.depends[z]; - if (!o || !match(n,o).v) { dirty=1; view.depends[z]=n; } - }) - if (dirty) { view.cache = run(view.r, this); } return view.cache; - } - return view; - }; -} - -function atx(x, y, env) { - return x.t == 2 ? atx(env.lookup(x), y, env) : y.t == 11 ? x : - x.t == 3 && y.t == 4 ? md(y.k, atx(x, y.v, env)) : - x.t == 8 || x.t == 9 ? applym(x, y, env) : - (x.t == 3 || x.t == 4) && y.t == 3 ? kmap(y, function(z) { return atx(x, z); }) : - x.t == 3 ? (y.t > 1 || y.v < 0 || y.v >= len(x) || y.v%1 != 0) ? NA : x.v[y.v] : - x.t == 4 ? dget(x, y) : call(x, enlist(y), env) -} - -function atdepth(x, y, i, env) { - if (i >= len(y)) { return x; }; var c = y.v[i]; var k = atx(x, c, env); - return (c.t != 11 && c.t != 3) ? atdepth(k, y, i+1, env) : - kmap(k, function(t) { return atdepth(t, y, i+1, env) }) -} - -function call(x, y, env) { - if (x.sticky) { return (valence(x.sticky, env)==1?applym:applyd)(x, y.v[0], y.v[1], env); } - if (x.t == 2) { return call(env.lookup(x), y, env); } - if (x.t == 3 || x.t == 4) { return y.t == 3 ? atdepth(x, y, 0, env) : atx(x, y, env); } - if (x.t == 8) { return applyverb(x, y.t == 3 ? y.v : [y], env); } - if (x.t == 9) { return applyadverb(x, run(x.verb, env), y.v, env); } - if (x.t != 5) { throw new Error("function or list expected, found " + TN[x.t]+'.'); } - if (y.t == 4) { var e=new Environment(null); e.d=y; x.env=e; return x; } - if (y.t != 3) { y = enlist(y); } - var environment = new Environment(x.env); var curry = x.curry?x.curry.concat([]):[]; - if (x.args.length != 0 || len(y) != 1 || !isnull(y.v[0]).v) { - var all=true; var i=0; for(var z=0;z= len(y)) { all=false; break; } - if (y.v[i] == null || isnull(y.v[i]).v) { all=false; } - curry[z]=y.v[i++]; - } - if (!all) { return { t:5, v:x.v, args:x.args, env:x.env, curry:curry }; } - if (i < len(y) && x.args.length != 0) { throw new Error("valence error."); } - for(var z=0;z=~,^#_$?@.]/; -var ASSIGN = /^[+\-*%!&|<>=~,^#_$?@.]:/; -var IOVERB = /^\d:/; -var ADVERB = /^['\\\/]:?/; -var SEMI = /^;/; -var COLON = /^:/; -var VIEW = /^::/; -var COND = /^\$\[/; -var DICT = /^\[[a-z]+:/i; -var OPEN_B = /^\[/; -var OPEN_P = /^\(/; -var OPEN_C = /^{/; -var CLOSE_B = /^\]/; -var CLOSE_P = /^\)/; -var CLOSE_C = /^}/; - -var des = {}; -des[NUMBER ]="number";des[NAME ]="name" ;des[SYMBOL ]="symbol";des[STRING]="string"; -des[VERB ]="verb" ;des[IOVERB ]="IO verb";des[ADVERB ]="adverb";des[SEMI ]="';'"; -des[COLON ]="':'" ;des[VIEW ]="view" ;des[COND ]="'$['" ; -des[OPEN_B ]="'['" ;des[OPEN_P ]="'('" ;des[OPEN_C ]="'{'" ;des[ASSIGN]="assignment"; -des[CLOSE_B]="']'" ;des[CLOSE_P]="')'" ;des[CLOSE_C]="'}'"; - -var text = ""; -var funcdepth = 0; -function begin(str) { - str = str.replace(/("(?:[^"\\\n]|\\.)*")|(\s\/.*)|([a-z\d\]\)]-\.?\d)/gi, function(_, x, y, z) { - // preserve a string (x), remove a comment (y), disambiguate a minus sign (z) - return x ? x : y ? "" : z.replace('-', '- ') - }) - text = str.trim().replace(/\n/g, ";"); funcdepth = 0; -} -function done() { return text.length < 1; } -function at(regex) { return regex.test(text); } -function matches(regex) { return at(regex) ? expect(regex) : false; } -function expect(regex) { - var found = regex.exec(text); - if (regex == OPEN_C) { funcdepth++; } if (regex == CLOSE_C) { funcdepth--; } - if (found == null) { throw new Error("parse error. "+des[regex]+" expected."); } - text = text.substring(found[0].length).trim(); return found[0]; -} - -//////////////////////////////////// -// -// Parser -// -//////////////////////////////////// - -function findNames(node, names) { - if (node == null) { return names; } - if (node instanceof Array) { node.forEach(function(v) { findNames(v, names); }); return names; } - if (node.t == 7) { names[node.v] = 0; } - if (node.t != 5) { findNames(node.v, names); } - return findNames([node.l, node.r, node.verb, node.curry], names); -} - -function atNoun() { - return !done()&&at(NUMBER)||at(NAME)||at(SYMBOL)||at(STRING)||at(COND)||at(OPEN_P)||at(OPEN_C); -} - -function indexedassign(node, indexer) { - var op = { t:5, args:["x","y"], v:[{ t:7, v:"y" }] }; // {y} - var gl = matches(COLON); - var ex = parseEx(parseNoun()); - //t[x]::z -> ..[`t;x;{y};z] t[x]:z -> t:.[t;x;{y};z] - if (!gl) { node.r = { t:8, v:".", curry:[ k(7,node.v), kl(indexer), op, ex] }; return node; } - return { t:8, v:".", r:{ t:8, v:".", curry:[ks(node.v), kl(indexer), op, ex] }}; -} - -function compoundassign(node, indexer) { - if (!at(ASSIGN)) { return node; } - var op = expect(ASSIGN).slice(0,1); var gl = matches(COLON); var ex = parseEx(parseNoun()); - if (!indexer) { - // t+::z -> t::(.`t)+z - var v = gl ? asVerb(".", null, ks(node.v)) : node; - return { t:node.t, v:node.v, global:gl, r:asVerb(op, v, ex) }; - } - // t[x]+::z -> ..[`t;x;+:;z] t[x]+:z -> t:.[t;x;{y};z] - if (!gl) { node.r={ t:8, v:".", curry:[ k(7,node.v),kl(indexer),asVerb(op),ex] }; return node; } - return asVerb(".", null, { t:8, v:".", curry:[ks(node.v), indexer, asVerb(op), ex] }); -} - -function applycallright(node) { - while (matches(OPEN_B)) { - var args = parseList(CLOSE_B); node = asVerb(".", node, k(3, args.length ? args : [NIL])); - } return node; -} - -function applyindexright(node) { - if (node.sticky && at(VERB)) { - var x = parseNoun(); x.l = node; x.r = parseEx(parseNoun()); return x; - } - while (matches(OPEN_B)) { node = asVerb(".", node, k(3, parseList(CLOSE_B))); } - return node; -} - -function findSticky(root) { - var n = root; if (n == null || (n.t == 9 && n.r == null)) { return; } - while(n.t == 8 && !n.curry || n.t == 9) { - if (n.r == null) { root.sticky = n; return; } n = n.r; - } -} - -function parseList(terminal, cull) { - var r=[]; do { - if (terminal && at(terminal)) { break; } - while(matches(SEMI)) { if (!cull) { r.push(k(11)); } } - var e = parseEx(parseNoun()); findSticky(e); - if (e != null) { r.push(e); } - else if (!cull) { r.push(k(11)); } - } while(matches(SEMI)); if (terminal) { expect(terminal); } return r; -} - -function parseNoun() { - if (matches(COLON)) { return { t:5, args:["x","y"], v:[{ t:7, v:"y" }] }; } // {y} - if (at(IOVERB)) { return k(8, expect(IOVERB)); } - if (at(BOOL)) { - var n = expect(BOOL); var r=[]; - for(var z=0;z@x;!x;x]}"), env); - run(parse("in:{~^y?x}"), env); - return env; -} - -var packimpl = parse("{+/y*|*\\1,|1_(#y)#x}")[0]; -var unpackimpl = parse("{(1_r,,y)-x*r:|y(_%)\\|x}")[0]; -var spliceimpl = parse("{,/(*x;$[99<@z;z x 1;z];*|x:(0,y)_x)}")[0]; -var winimpl = parse("{$[0>x;3':0,y,0;y(!0|1+(#y)-x)+\\:!x]}")[0]; -var odoimpl = parse("{+x\\'!*/x}")[0]; -var splitimpl = parse("{1_'(&x=y)_y:x,y}")[0]; - -// export the public interface: -function setIO(symbol, slot, func) { - if (!(symbol in verbs)) { verbs[symbol]=[null,null,null,null,null,null]; } - verbs[symbol][slot] = func; -} - -this.version = "0.1"; -this.parse = parse; -this.format = format; -this.run = run; -this.Environment = Environment; -this.baseEnv = baseEnv; -this.setIO = setIO; diff --git a/ok/readme.txt b/ok/readme.txt index d195ef0..0a8b83a 100644 --- a/ok/readme.txt +++ b/ok/readme.txt @@ -1 +1,5 @@ -This is just https://github.com/johnearnest/ok but with some extra files made by me. +Step 1: Get a copy of https://github.com/johnearnest/ok +Step 2: Append appendoK.js to oK.js +Step 3: Use ircrepl.js with it. +Step 4: ??? +Step 5: Be sad. diff --git a/ok/repl.js b/ok/repl.js deleted file mode 100755 index 984af65..0000000 --- a/ok/repl.js +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env node -var ok = require('./oK'); -var fs = require('fs'); -var os = require('os'); -var path = require('path'); -var readline = require('readline'); -var conv = require('./convert'); - -// register I/O hooks -function str(x) { // convert a k string or symbol to a js string - var s = conv.tojs(x); - if (typeof s !== 'string') { throw Error('ERROR: type'); } - return s; -} -function read(x) { - var f = str(x); - if (f) { - f = path.resolve(process.cwd(), f); - return conv.tok(fs.statSync(f).isDirectory() ? fs.readdirSync(f) : fs.readFileSync(f, 'utf8').replace(/\r?\n$/, '').split(/\r?\n/)); - } else if (rl) { - throw Error('ERROR: cannot read from stdin while in REPL'); - } else { - var b = Buffer(128), b0, n = 0; - while (fs.readSync(process.stdin.fd, b, n, 1) && b[n] !== 10) { - n++; - if (n === b.length) { b0 = b; b = Buffer(2 * n); b0.copy(b, 0, 0, n); b0 = null; } // resize buffer when full - } - return conv.tok(b.toString('utf8', 0, n)); - } -} -function write(x, y) { - var s = conv.tojs(y); - if (Array.isArray(s)) { s = s.join('\n') + '\n'; } - if (typeof s !== 'string') { throw Error('ERROR: type'); } - var f = str(x); - if (f) { - fs.writeFileSync(path.resolve(process.cwd(), f), s); - } else { - fs.writeSync(process.stdout.fd, s); - } - return y; -} -for (var i = 0; i < 2; i++) { ok.setIO('0:', i, read ); } -for (var i = 2; i < 6; i++) { ok.setIO('0:', i, write); } -for (var i = 0; i < 2; i++) { ok.setIO('5:', i, function(x) { return conv.tok(ok.format(x)); }); } - -var env = ok.baseEnv(); - -// run user prelude file if exists -try { - var preludeFile = os.homedir() + "/.config/okrc.k" - var program = fs.readFileSync(preludeFile, 'utf8'); - ok.run(ok.parse(program), env) -} catch (err) { - if (err.code != 'ENOENT') throw err -} - -// process filename.k as a command-line arg -if (process.argv.length > 2) { - var program = fs.readFileSync(process.argv[2], 'utf8'); - env.put('x', true, conv.tok(process.argv.slice(3))) - process.stdout.write(ok.format(ok.run(ok.parse(program), env)) + '\n'); - process.exit(0); -} - -// actual REPL -process.stdout.write('oK v' + ok.version + '\n'); -var rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, - completer: function (line) { - var m = /[a-z][a-z\d]*$/i.exec(line); - var prefix = m ? m[0] : ''; - var names = []; - for (var e = env; e; e = e.p) { // iterate over ancestor environments - for (var name in e.d) { - if (name.slice(0, prefix.length) === prefix && names.indexOf(name) < 0) { - names.push(name); - } - } - } - return [names, prefix]; - } -}); -rl.on('line', function (line) { - if (line === '\\\\') { process.exit(0); } - var showtime = false; - if (line.lastIndexOf("\\t") == 0) { - line = line.slice(2); - showtime = true; - } - try { - if (line.trim()) { - var starttime = new Date().getTime(); - var output = ok.format(ok.run(ok.parse(line), env)) + '\n'; - if (showtime) { - var endtime = new Date().getTime(); - output += "completed in "+(endtime-starttime)+"ms.\n"; - } - process.stdout.write(output); - } - } catch (err) { - process.stdout.write(err.message + '\n'); - } - rl.prompt(); -}); -rl.on('close', function () { process.stdout.write('\n'); process.exit(0); }); -rl.setPrompt(' '); rl.prompt();