Compiler for a small concatenative and purely functional programming language for making visuals. The draw function takes the time, x and y, and returns the color of that pixel. Press Enter to compile…
_='k=`,l=0,m={"++L**L^^L%U%vL<U<vsKMVh.sin()d!vpK;x!wL?",x=;x?w:vcK(h!(w"},r={":$:Z;Qd[g[f+1]]=2)RS[$[Z]QR7("+1))+"}S( RpW(Z)Q)]}};7 pe+=1;h=1;0<h&&e<f)Ad?h:Ag&&h--;--e}7 qf="BgGg[e];rN?(_=rN)+=_[0]=_[1]):f+YN||""+h+""} f}7 s(~kd=ca,a#l;g=[]=0;f<d#;f)Bd;G4*(e+f*dg9lk(gn=g@n816H5}c.putd,0,0)}}onsize(H6,H6tYocumXtElemXtWtextaa"=": J[ xPh x ;\\n: JdT% H6 < [ JJ^ *P[ * * sT*P? c ;";b.appXdChild(tt.onkeydown=7(d~13=Y.which&&d=Object(mg=q(d,.trim().split(/\\s+/g)(g))([]kY.?d.):`;s()}};setInterval(s,50s@s9unctionvaJ;d.dVa[h]=);Kv=Z, ":7_urn(d,gfor(.cVet.value.widthq.slice(f+){ImageDVa(new FWs"K&H5,w=,f.lXgth;,ere++draw!;v#.height$ e=pW7f9.push(@.pop()Af[e]==Be=0;e<Geh=H25Jr K:"L"N[h]P ] QgR["Se]},"T 512 U";VatW("XenY=dZ"_t`null~if(n>>';for(Y in $='~`_ZYXWVUTSRQPNLKJHGBA@97$#! ')with(_.split($[Y]))_=join(pop());eval(_)
Xz0nBGs9YCxsPTAsbT17IisXKwFMKhcqAUxeF14BTCVVJXZMPFU8dhFzSwJNVmguc2luKAEpEWQHIQJ2EXBLATsIeBkhAndMPyIZLHg9ATsCeD93OnYRY0sBKBFoGSEBKAYCdwYifSxyPXsiOiQ6WjtRBmRbZ1tmKzFdXT0TMhwpBlIIU1skW1pdUQZSAjcoFCIrEzEcKSkrIn0RUygJUghwVyhaKVEpXX19OzcgcAwaHBRlKz0xOw5oPTE7MDxoJiZlPGYbKUFkP2geOkFnJiZoLS0cHjsLLS1lfTcgcQwUDmY9IghCZxtHZ1tlXTtyTj8oXz1yTgwcKRorPV9bMF0cPV9bMV0pOmYrWU58fCICIitoKyIGIn0LIGZ9NyBzKH5rFARkPWMPFWESLGEjBmweOw5nPVtdGj0wO2Y8ZCM7Zh4pDkJkEjtHNCooZStmKmQSBmc5bBocBmsoZwYEbj1nQAVufzh/MTYYSDV9Yy5wdXQVZCwwLDApfX1vbh1zaXplKEg2LEg2BnRZb2N1bVh0D0VsZW1YdFd0ZXh0YR1hIgYQPSI6IEpbIHhQaCB4IDtcXG46IB8gSmRUJSBINiA8IFsgSkpeICpQWyAqICogc1QqUD8gYyA7IjtiLmFwcFhkQ2hpbGQodAZ0Lm9ua2V5ZG93bj03KGR+MTM9WS53aGljaCYmEBRkPU9iamVjdA8obQYEZz1xKGQsEC50cmltKCkuc3BsaXQoL1xccysvZykGKBZnKSkoW10Ga1kuHz8WZC4fKTpgO3MoKX19O3NldEludGVydmFsKHMsNTAGAXNAAnM5A3VuY3Rpb24EdmFKBTtkLmRWYVtoHl09Bik7B0sEdj0BWiwJIjo3DBoUC191cm4MKGQsZw5mb3IoBA8uYx1WZRB0LnZhbHVlEQYIEi53aWR0aBNxDC5zbGljZShmKxQpexVJbWFnZURWYSgWbmV3IEYDV3MIFyJLAgEYJkg1BRkHLHc9ARosZhsubFhndGg7HCxlHXJlHisrH2RyYXchOwJ2BiMuaGVpZ2h0JAkEZT1wVzdmAzkucHVzaChALnBvcCgpQWZbZV09PUJlPTA7ZTxHZR4UBGg9SDI1SnIgSzoiTBEiTltoXVAgXSBRCGcaUgtbIlNlXX0sIlQgNTEyIFUiBzsCAVZhdFcoIlhlblk9ZFoIIl8ddGBudWxsfhRpZih/GG4+Pic7Zm9yKFkgaW4gJD0nf35gX1pZWFdWVVRTUlFQTkxLSkhHQkFAOTckIyEfHh0cGxoZGBcWFRQTEhEQDw4MCwkIBwYFBAMCAScpd2l0aChfLnNwbGl0KCRbWV0pKV89am9pbihwb3AoKSk7ZXZhbChfKQ==
var drawingfn = null;
var time = 0;
var dictionary = {
// Math
"+": "s.push(s.pop()+s.pop());",
"*": "s.push(s.pop()*s.pop());",
"^": "s.push(s.pop()^s.pop());",
"%": "var v=s.pop();s.push(s.pop()%v);",
"<": "var v=s.pop();s.push(s.pop()<v);",
"s": "s.push(Math.sin(s.pop()));",
// "cos": "s.push(Math.cos(s.pop()));",
// "tan": "s.push(Math.tan(s.pop()));",
// Stack shuffling
"d": "var v=s.pop();s.push(v);s.push(v);",
"p": "s.pop();",
"x": "var v=s.pop(),w=s.pop();s.push(v);s.push(w);",
// "rot": "var v = s.pop(), w = s.pop(), x =s.pop(); s.push(w,v,x);",
"?": "var v=s.pop(),w=s.pop(),x=s.pop();s.push(x?w:v);",
"c": "s.pop()();",
"h": "var v=s.pop(),w=s.pop();s.push(v);s.pop()();s.push(w);"
// debug
// "dbg": "console.log(s.pop());"
};
var specials = {
":": function(dict, tokens, idx) {
var end = matchingIndex(":", ";", tokens, idx);
dict[tokens[idx+1]] = compile(dict, tokens.slice(idx+2,end));
return ["", end];
},
"[": function(dict, tokens, idx) {
var end = matchingIndex("[", "]", tokens, idx);
return ["s.push(function(){" + compile(dict, tokens.slice(idx+1,end)) + "});", end];
},
"(": function(dict, tokens, idx) {
var end = matchingIndex("(", ")", tokens, idx);
return ["", end];
}
// "'": function(_, tokens, idx) { return ["s.push('" + tokens[idx+1] + "');", idx+1]; }
};
var matchingIndex = function(left, right, tokens, startIdx) {
var i = startIdx + 1, balance = 1;
while(balance > 0 && i < tokens.length) { // todo: forloopify
if(tokens[i] == left) balance++;
else if(tokens[i] == right) balance--;
i++;
}
return --i;
}
var compile = function(dict, tokens) {
var str = "";
for(var i = 0; i < tokens.length; i++) {
var token = tokens[i];
if(specials[token]) {
ret = specials[token](dict, tokens, i);
str += ret[0];
i = ret[1];
} else {
str += dict[token] || ("s.push(" + token + ");");
}
}
return str;
}
var i = function (stack, dict, str){
var js = compile(dict, str.trim().split(/\s+/g));
return new Function("s", js)(stack);
}
//Drawing
var draw = function() {
if(!drawingfn) return;
var img = c.createImageData(a.width, a.height);
time++ //= Date.now();//%512;
var s = [];
for(var y = 0; y < img.height; y++) {
for(var x = 0; x < img.width; x++) {
var index = (x + y * img.width) * 4;
s.push(time, y, x);
//var s = [time, y, x];
drawingfn(s);
//var b = s.pop(), g = s.pop(), r = s.pop();
var color = s.pop();
img.data[index++] = color & 255; // r
img.data[index++] = (color >> 8) & 255; // g
img.data[index++] = (color >> 16) & 255; // b
img.data[index++] = 255; // a
}
}
c.putImageData(img, 0, 0);
}
// TODO: real dip, better solution ot swapping out draw?
var init = function() {
onresize(256,256);
t = document.createElement("textarea");
t.value = ": r [ x ] h x ;\n: draw r d 512 % 256 < [ r r ^ * ] [ * * s 512 * ] ? c ;";
b.appendChild(t);
// Shift + Enter to eval and draw
t.onkeydown = function(e) {
if(e.which == 13 && t.value) {
var stack = [];
var dict = Object.create(dictionary);
i(stack, dict, t.value);
drawingfn = dict.draw ? new Function("s", dict.draw) : null;
draw();
// e.preventDefault(); // stop Enters newline
}
};
setInterval(draw, 50);
}
init();