minimal-lisp
Advanced tools
| for(_='fir+get/map@ndQbject^",qq")`)()O^H,["G"],L"GKKfnKZL["YZaY%K($s%.H$#)bDaDCZC)cYBconWWcatVYVK`KUArrayT!1,!0})x|le{empty?z)a:Z&:Y9st8pr7li867-6*5pply4L"3def)2]]]G2"a"LntclassOfototypeK.-__aQ?%=q]coains?.)Ref{ct$Property38|ssliceZCY:DL}or_FIXME"]]G$7(tring ifK8r95:$nullY+6$ifY(cou)K~Z&|sYz|sLn97iK5:$ L!G=q1Gxs+Y6${tY6$modu{.exports=["doK2isa.DisPrOfnewZa)&DYW8ruct3C"delde{teC"7i%doK.)Wso{$log3aL7*%.)JSON$s ify@.D$@YfnKxYa|"]6Z&:3a2>=<>>=:DY=],!1<=>%.HtoS (callnot%if:q},true!0,false!1,s ["([o^ S ]Y:"5B{tKl8K@ZxYif)cK7*|Ys ?|3xK7*|"]]]],"a.)l8$join3b"7- L!0L!1707il16?%.)T$isT.:$hasOwnb"/:DY.-:DLsetBdo:D)ckey#keysval#valuesWs.K`q[]]G(VY6:3b"V9.K6Y(V`:4Y6h)/Y2cou%.-:${ngth"+8%>KaL0]Gh:q0],la8%h:K-KaL1z%6?:Y=q0Ga=:qZC)&)eQY.:$3bK>KeQL0]G/)eQq0]Ga"]re8%:q1a4Zf)&DY.)fK`:43fKVKDq0,-1]Gla8D"]aQ!0UaQre("]]]]orY(Uorre"]]]]]]]]],];';G=/[-2-:z-}T-WB-D#-%YZKLGH()q^Q@/+]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
| require("repl").start({eval:(...r)=>r[3](0,r[0].trim()),writer:(...r)=>r[0]}); |
| require("repl").start({eval:(...r)=>r[3](0,r[0].trim()),writer:(...r)=>r[0]}); |
| // miniMAL | ||
| // Copyright (C) 2024 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| // Node specific | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,a[0].trim()), | ||
| writer: (...a) => a[0]}) |
| for(_='in@,eI[tK,[q","z"q"||`z$val#"==_,t^(e5))4map3(n,R),Q.35=>P1)PaRe)QG.slice(Ft=rFGEJSON.DArrayCif(B)=>Z]]Y[0]X[1]WtXKW]V.#ueUfac| @ ?n[rtypeof Object.("\\n")throwelse{B(5^Z[2]return e){a(iReW,"(...^X.onkeyuptextareafunctionY]\\n[":eZr.at(-1);B" aRrn=create(nQrassign(< rows=9 cols=60>;else B_rX)"eXEx=V, iRr,i){.some"&_eK+1Y=iFt):(n[e]=iK],0)Qn} I^){for(;;){B!C.isC(r4"_r?rn]:A.(r+" not found"):r defn[rW]=) ~WQ{M:1}) `rW .-2t?V=t:x .x.apply(tX^F24 trytry{W)}catch([W]qe]Q)}"fnrWIQ)}qr,n,rW]) letW.3t%2WK-1Y=WK]):0Qr="dorF1,-Gr="ifr=W)?r:5=X4.M)r=erF14;E!(0e4et);r=eX,n=i5WI^)}}}}A=this,{js:e#I#a(AIXQ"====<<++--**//eW,3:tZtWPtX5)Q{ eX}}Qb.@nerHTML=\'["let|m$m@i"Yq"+zm$MAL"defzfn|n"]q"ifzn|*zn|-zn",1Y],13z`"q7,8,9.zMath$random"Y</></>\'^=b.children=(ZtWU=tXU.splitPe?Dstr@gify(a(A,Dparse54):"").jo@()';G=/[-U-ZB-GP-R3-5^_#$|zqKI@]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
+34
-39
| ["do", | ||
| ["def", "isa", ["fn", ["a", "b"], | ||
| [".", [".-", "b", ["`", "prototype"]], ["`", "isPrototypeOf"], "a"]]], | ||
| ["def", "new", ["fn", ["a", "&", "b"], | ||
@@ -7,2 +9,7 @@ [".", "Reflect", ["`", "construct"], "a", "b"]]], | ||
| [".", "Reflect", ["`", "deleteProperty"], "a", "b"]]], | ||
| ["def", "print", ["fn", ["a"], | ||
| ["do", [".", "console", ["`", "log"], "a"], null]]], | ||
| ["def", "pr*", ["fn", ["a"], | ||
| [".", "JSON", ["`", "stringify"], "a"]]], | ||
| ["def", "map", ["fn", ["a", "b"], | ||
@@ -30,32 +37,21 @@ [".", "b", ["`", "map"], ["fn", ["x"], ["a", "x"]]]]], | ||
| ["def", "string?", ["fn", ["a"], | ||
| ["if", ["=", "a", null], | ||
| false, | ||
| ["=", ["`", "String"], | ||
| [".-", [".-", "a", ["`", "constructor"]], | ||
| ["`", "name"]]]]]], | ||
| ["=",["`","[object String]"], ["classOf","a"]]]], | ||
| ["def", "pr-list*", ["fn", ["a", "b", "c"], | ||
| ["let", ["lst", ["map", ["fn", ["x"], | ||
| ["if", "c", | ||
| ["pr*", "x"], | ||
| ["if", ["string?", "x"], | ||
| "x", | ||
| ["pr*", "x"]]]], | ||
| "a"]], | ||
| [".", "lst", ["`", "join"], "b"]]]], | ||
| ["def", "pr-str", ["fn", ["&", "a"], | ||
| [".", ["map", [".-", "JSON", ["`", "stringify"]], "a"], | ||
| ["`", "join"], ["`", " "]]]], | ||
| ["pr-list*", "a", ["`", " "], true]]], | ||
| ["def", "str", ["fn", ["&", "a"], | ||
| [".", ["map", ["fn", ["x"], | ||
| ["if", ["string?", "x"], | ||
| "x", | ||
| [".", "JSON", ["`", "stringify"], "x"]]], | ||
| "a"], | ||
| ["`", "join"], ["`", ""]]]], | ||
| ["pr-list*", "a", ["`", ""], false]]], | ||
| ["def", "prn", ["fn", ["&", "a"], | ||
| ["do", [".", "console", ["`", "log"], | ||
| [".", ["map", [".-", "JSON", ["`", "stringify"]], "a"], | ||
| ["`", "join"], ["`", " "]]], | ||
| null]]], | ||
| ["print", ["pr-list*", "a", ["`", " "], true]]]], | ||
| ["def", "println", ["fn", ["&", "a"], | ||
| ["do", [".", "console", ["`", "log"], | ||
| [".", ["map", ["fn", ["x"], | ||
| ["if", ["string?", "x"], | ||
| "x", | ||
| [".", "JSON", ["`", "stringify"], "x"]]], | ||
| "a"], | ||
| ["`", "join"], ["`", " "]]], | ||
| null]]], | ||
| ["print", ["pr-list*", "a", ["`", " "], false]]]], | ||
@@ -76,4 +72,3 @@ ["def", "list?", ["fn", ["a"], | ||
| ["def", "cons", ["fn", ["a", "b"], | ||
| [".", ["`", []], | ||
| ["`", "concat"], ["list", "a"], "b"]]], | ||
| [".", ["`", []], ["`", "concat"], ["list", "a"], "b"]]], | ||
| ["def", "concat", ["fn", ["&", "a"], | ||
@@ -83,19 +78,19 @@ [".", [".-", ["list"], ["`", "concat"]], | ||
| ["def", "nth", "get"], | ||
| ["def", "count", ["fn", ["a"], | ||
| [".-", "a", ["`", "length"]]]], | ||
| ["def", "first", ["fn", ["a"], | ||
| ["if", [">", [".-", "a", ["`", "length"]], 0], | ||
| ["if", [">", ["count", "a"], 0], | ||
| ["nth", "a", 0], | ||
| null]]], | ||
| ["def", "last", ["fn", ["a"], | ||
| ["nth", "a", ["-", [".-", "a", ["`", "length"]], 1]]]], | ||
| ["def", "count", ["fn", ["a"], | ||
| [".-", "a", ["`", "length"]]]], | ||
| ["nth", "a", ["-", ["count", "a"], 1]]]], | ||
| ["def", "empty?", ["fn", ["a"], | ||
| ["if", ["list?", "a"], | ||
| ["=", 0, [".-", "a", ["`", "length"]]], | ||
| ["=", 0, ["count", "a"]], | ||
| ["=", "a", null]]]], | ||
| ["def", "slice", ["fn", ["a", "b", "&", "end"], | ||
| [".", "a", ["`", "slice"], "b", | ||
| ["if", [">", [".-", "end", ["`", "length"]], 0], | ||
| ["if", [">", ["count", "end"], 0], | ||
| ["get", "end", 0], | ||
| [".-", "a", ["`", "length"]]]]]], | ||
| ["count", "a"]] ]]], | ||
| ["def", "rest", ["fn", ["a"], ["slice", "a", 1]]], | ||
@@ -110,3 +105,3 @@ | ||
| true, | ||
| ["if", ["=", 1, [".-", "xs", ["`", "length"]]], | ||
| ["if", ["=", 1, ["count", "xs"]], | ||
| ["first", "xs"], | ||
@@ -121,7 +116,7 @@ ["list", ["`", "let"], ["list", ["`", "__and"], ["first", "xs"]], | ||
| null, | ||
| ["if", ["=", 1, [".-", "xs", ["`", "length"]]], | ||
| ["if", ["=", 1, ["count", "xs"]], | ||
| ["first", "xs"], | ||
| ["list", ["`", "let"], ["list", ["`", "__or"], ["first", "xs"]], | ||
| ["list", ["`", "if"], ["`", "__or"], | ||
| ["`", "__or"], | ||
| ["list", ["`", "let"], ["list", ["`", "or_FIXME"], ["first", "xs"]], | ||
| ["list", ["`", "if"], ["`", "or_FIXME"], | ||
| ["`", "or_FIXME"], | ||
| ["concat", ["`", ["or"]], ["rest", "xs"]]]]]]]]], | ||
@@ -128,0 +123,0 @@ |
+1
-1
@@ -1,1 +0,1 @@ | ||
| for(_='rekkturn z;z|]=$in#,iL))K.slice(__1K^,rI(nHt(G[1]RI)QnRPGPQ7"==6[0]5if4letE{E e=Dn5C6C)BBDZZiH_1Y),Xe5WIXt=WVJSON.Un=T[e)=>t.A[2]ne){zG # for(,e,"utf8"Object.P,"throw(...:n"C:en.length-1#stanceof 4("}else typeof Array!HKziHQ;Uparse(functionckate(kquik("fs").kadFileSync(Y)VR]|module.exports=H){ eH){;n&&C# e&&e[C].M;)Te[C]n^|n} GnQ{;;){4(4(TeHIXdefBzr[P$GQ;~Z7|e.M=1}`BzP;.-2e?WR$e:t}.t.apply(W_2K}tryBtry{z7}catch(L([R]I,]K fnZL(PIK}|e.A=[I,P]}EB{r=r);E eP)e%2&&(r[P-1]$GP]Q);T doY,Xr);Tn[] 4BT7?:n[3];elseDiHV;4(!)zte^;T5I=i(,R^}}}E i=(eLQ{zr?(i=i).some(H,t"&6n?i[t+1]$r_t):(i[n$r[t],0)Xi):e?e.map(nGCLK:"6e?ei?i]:n.(e+" not found"):e}|Tassign(nX{js:evalvalGW,nX"====<<++--**//PLsaCP,typeC,newnew(C.b#dn)XdeldeEe C[P],{ C}IeadCXslurpCXloadGW)XnXkpUstr#g4y(GWXnK})}';G=/[-T-ZB-E4-7P-RG-I^_KL#$|zk]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='reZ[0]Y"==iY)XZturn WXWVi=U(t,TaTiR]=RQ[1]PeP,I,r)H))G),E1).map(e=>aTe)ED.slice(Cr=iCDB[rrYP]JSON.Arrayif(typeof ==i?i in ?t[ithrowObject.cZate(else{(...eY:e)=>"[2]e){Wa(sTI"assign( ((eH=>parse()t=tEii.at(-1)function;";else VBx=,module.exports=(n){ sTi,n){W.some"&"==e+1]]=nCr):(t[e]=n],0)Et} R,eH{for(;;){!.is(iGW""t]:n.(i+" not found"):{}&&keys(i).Zduce(eQ]EeE{}):idefVt[iPQ)~V RPE{M:1})`ViP.-2r?=r:x.x.apply(rY,rC2GtryXtry{WRP)}catch([P],[e]E)}"fnV iP,eE)},[i,t,iP])letXP.mapr%2P-1]QP]):0EU"doXiC1,-DU"ifXURP)?i:(e=RYG.M)UeiC1G;B!(0eGWer);U,t=s(IeH}}}}Wn= nE{js:eval,evala(n,E"====<<++--**//I{ },Zad,slurpZquiZ("fs").ZadFileSync(,"utf8"EZpstringify(a(n,G})};';G=/[^ -AFJ-OS[-~]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
+34
-6
| { | ||
| "name": "minimal-lisp", | ||
| "version": "1.0.3", | ||
| "version": "1.2.1", | ||
| "description": "miniMAL: a Clojure-inspired Lisp in < 1024 bytes of JavaScript", | ||
| "keywords": ["Clojure", "clojure", "Lisp", "lisp", "mal", "make-a-lisp", "1K", "1024", "golf", "JS1K", "js1k", "JSON", "json", "tail-call", "TCO", "macros", "interop", "lexical", "functional"], | ||
| "keywords": [ | ||
| "Clojure", | ||
| "clojure", | ||
| "Lisp", | ||
| "lisp", | ||
| "mal", | ||
| "make-a-lisp", | ||
| "1K", | ||
| "1024", | ||
| "golf", | ||
| "JS1K", | ||
| "js1k", | ||
| "JSON", | ||
| "json", | ||
| "tail-call", | ||
| "TCO", | ||
| "macros", | ||
| "interop", | ||
| "lexical", | ||
| "functional" | ||
| ], | ||
| "homepage": "http://kanaka.github.io/miniMAL", | ||
@@ -13,8 +33,10 @@ "repository": { | ||
| "main": "miniMAL-node.js", | ||
| "bin": { "miniMAL": "./miniMAL" }, | ||
| "bin": { | ||
| "miniMAL": "./miniMAL" | ||
| }, | ||
| "files": [ | ||
| "miniMAL", | ||
| "miniMAL-node.js", | ||
| "miniMAL-core.js", | ||
| "index.js", | ||
| "miniMAL-min.js", | ||
| "miniMAL-js1k.js", | ||
@@ -26,5 +48,11 @@ "step*.js", | ||
| "devDependencies": { | ||
| "uglify-js": "2.7.5", | ||
| "jscrush": "0.0.0" | ||
| "async": "^3.2.2", | ||
| "jscrush": "0.0.0", | ||
| "source-map": "0.7.3", | ||
| "uglify-js": "3.14.5", | ||
| "yargs": "^17.3.1" | ||
| }, | ||
| "dependencies": { | ||
| "nbb": "^1.2.187" | ||
| } | ||
| } |
@@ -1,1 +0,1 @@ | ||
| !function(){function n(n,r){return n}require("repl").start({eval:(...r)=>r[3](0,n(JSON.parse(r[0]),{})),writer:JSON.stringify,terminal:0})}() | ||
| function r(r,e){return e}require("repl").start({eval:(...r)=>r[3](0,JSON.stringify(JSON.parse(r[0]))),writer:(...r)=>r[0]}) |
@@ -1,1 +0,1 @@ | ||
| !function(){function n(n,r){return n}require("repl").start({eval:(...r)=>r[3](0,n(JSON.parse(r[0]),{})),writer:JSON.stringify,terminal:0})}() | ||
| function r(r,e){return e}require("repl").start({eval:(...r)=>r[3](0,JSON.stringify(JSON.parse(r[0]))),writer:(...r)=>r[0]}) |
+4
-10
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Copyright (C) 2024 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| !function() { | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast) { | ||
| return ast | ||
| } | ||
| // Node specific | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,EVAL(JSON.parse(a[0]),{})), | ||
| writer: JSON.stringify, | ||
| terminal: 0}) | ||
| }() | ||
| eval: (...a) => a[3](0,JSON.stringify(EVAL({}, JSON.parse(a[0])))), | ||
| writer: (...a) => a[0]}) |
@@ -1,1 +0,1 @@ | ||
| _='!z(){z nh{if(!(n|))xth;let r=th,f=rb;xf.apply(f,r.slice(1))}let t=z(t_{xt|?t.map(jn(tb_):d""==dt?t in i?i[t]:null[t]:t};A={"+~+k-~-k*~*k/~/n[1]},require("repl").start({eval:jt[3](0,n(`parse(tb),A)),writer:`stringify,terminal:0})}()~":(...n)=>nb| instanceof Arrayzfunctionxreturn kn[1],"j(...t)=>h(n_dtypeof b[0]`JSON._,i)';for(i of'_`bdhjkxz|~')with(_.split(i))_=join(pop());eval(_) | ||
| _='function ki,r,n){return b.isb(i)?_ki`(...n=i.slic^1).map_>kr))):x""==xi?i in t?t[i]:_>{throw i+" not found"})():i}A={"+z+|-z-|*z*|/z/r[1]},requir^"repl").start({eval~3](0jstringify(^Ajpars^r`)),writer~0]})~:(...r)=>r[|r[1],"z"~0]xtypeof k^t,j,JSON.bArray`[0]))_(r=^e(';for(i of'^_`bjkxz|~')with(_.split(i))_=join(pop());eval(_) |
@@ -1,1 +0,1 @@ | ||
| !function(){function n(n,i){if(!(n instanceof Array))return t(n,i);let r=t(n,i),f=r[0];return f.apply(f,r.slice(1))}let t=function(t,i){return t instanceof Array?t.map((...t)=>n(t[0],i)):typeof ""==typeof t?t in i?i[t]:null[t]:t};E={"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1]},require("repl").start({eval:(...t)=>t[3](0,n(JSON.parse(t[0]),E)),writer:JSON.stringify,terminal:0})}() | ||
| function e(t,i,r,n){return Array.isArray(i)?(r=e(t,i[0]))(...n=i.slice(1).map(r=>e(t,r))):typeof ""==typeof i?i in t?t[i]:(r=>{throw i+" not found"})():i}E={"+":(...r)=>r[0]+r[1],"-":(...r)=>r[0]-r[1],"*":(...r)=>r[0]*r[1],"/":(...r)=>r[0]/r[1]},require("repl").start({eval:(...r)=>r[3](0,JSON.stringify(e(E,JSON.parse(r[0])))),writer:(...r)=>r[0]}) |
+23
-30
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Copyright (C) 2024 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| !function() { | ||
| let eval_ast = function(ast, env) { | ||
| // Evaluate the form/ast | ||
| return ast instanceof Array // list? | ||
| ? ast.map((...a) => EVAL(a[0], env)) // list | ||
| : (typeof ast == "string") // symbol? | ||
| ? ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : null[ast] // undefined symbol | ||
| : ast // ast unchanged | ||
| } | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast, f, el) { | ||
| //console.log("EVAL:", ast) | ||
| if (!(ast instanceof Array)) return eval_ast(ast, env) | ||
| // apply | ||
| let el = eval_ast(ast, env), | ||
| f = el[0] | ||
| return f.apply(f, el.slice(1)) | ||
| if (!Array.isArray(ast)) { | ||
| // eval | ||
| if (typeof ast == "string") { | ||
| return ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : (a => {throw ast + " not found"})() // undefined symbol | ||
| } else { | ||
| return ast | ||
| } | ||
| } else { | ||
| // apply | ||
| f = EVAL(env, ast[0]) | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| return f(...el) | ||
| } | ||
| } | ||
| E = { | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| } | ||
@@ -37,6 +33,3 @@ | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,EVAL(JSON.parse(a[0]),E)), | ||
| writer: JSON.stringify, | ||
| terminal: 0}) | ||
| }() | ||
| eval: (...a) => a[3](0,JSON.stringify(EVAL(E, JSON.parse(a[0])))), | ||
| writer: (...a) => a[0]}) |
@@ -1,1 +0,1 @@ | ||
| for(_='ren(,i)[t],r)JSON.;if("[0]"==i)t in i[1]n,"let typeof (i(...t)=>=Object.i[2]function instanceof Arrayturn ":(...n)=>n!(){ n{if(!(i))tdefr[i]=let{rcate(r);for()t%2&&(r[i[t-1]]=i);}{n=t,e=n;e.apply(e,n.slice(1))}}t=(t{t?t.map(t): ""== t??i:null:t},iassigthis,{"++--**//n});qui("pl").start({eval:t[3](0,parse(t)),writer:stringify,terminal:0})}()';G=/[-]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| _='function |,r,e){Uturn Z.isZ(i)?"defkVz]=W:"letk(t=Object.cUate(t),izY(r,e)=>e%2?Vz[e-1]]=|z[e]):0),W):(r=|X(...e=i.slice(1)Yr=>n(t,r))):`""==`i?i in t?V]:(r=>{throw i+" not found"})():i}A={"+x+_-x-_*x*_/x/rz},UquiU("Upl").start({eval~3](0^stringify(n(A^parse(rX)),writer~0]})~:(...r)=>r[|n(t,iz[1]x"~0]k"==i[0]?`typeof _rz,"^,JSON.ZArrayY.map(X[0]))W|[2])Vt[iUre';for(i of'UVWXYZ^_`kxz|~')with(_.split(i))_=join(pop());eval(_) |
@@ -1,1 +0,1 @@ | ||
| !function(){function n(i,r){if(!(i instanceof Array))return t(i,r);if("def"==i[0])return r[i[1]]=n(i[2],r);if("let"==i[0]){r=Object.create(r);for(let t in i[1])t%2&&(r[i[1][t-1]]=n(i[1][t],r));return n(i[2],r)}{let n=t(i,r),e=n[0];return e.apply(e,n.slice(1))}}let t=function(t,i){return t instanceof Array?t.map((...t)=>n(t[0],i)):typeof ""==typeof t?t in i?i[t]:null[t]:t},i=Object.assign(this,{"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1]});require("repl").start({eval:(...t)=>t[3](0,n(JSON.parse(t[0]),i)),writer:JSON.stringify,terminal:0})}() | ||
| function n(t,i,r,e){return Array.isArray(i)?"def"==i[0]?t[i[1]]=n(t,i[2]):"let"==i[0]?(t=Object.create(t),i[1].map((r,e)=>e%2?t[i[1][e-1]]=n(t,i[1][e]):0),n(t,i[2])):(r=n(t,i[0]))(...e=i.slice(1).map(r=>n(t,r))):typeof ""==typeof i?i in t?t[i]:(r=>{throw i+" not found"})():i}E={"+":(...r)=>r[0]+r[1],"-":(...r)=>r[0]-r[1],"*":(...r)=>r[0]*r[1],"/":(...r)=>r[0]/r[1]},require("repl").start({eval:(...r)=>r[3](0,JSON.stringify(n(E,JSON.parse(r[0])))),writer:(...r)=>r[0]}) |
+31
-42
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Copyright (C) 2024 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| !function() { | ||
| let eval_ast = function(ast, env) { | ||
| // Evaluate the form/ast | ||
| return ast instanceof Array // list? | ||
| ? ast.map((...a) => EVAL(a[0], env)) // list | ||
| : (typeof ast == "string") // symbol? | ||
| ? ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : null[ast] // undefined symbol | ||
| : ast // ast unchanged | ||
| } | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast, f, el) { | ||
| //console.log("EVAL:", ast) | ||
| if (!(ast instanceof Array)) return eval_ast(ast, env) | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(ast[2], env) | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| if (!Array.isArray(ast)) { | ||
| // eval | ||
| if (typeof ast == "string") { | ||
| return ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : (a => {throw ast + " not found"})() // undefined symbol | ||
| } else { | ||
| return ast | ||
| } | ||
| } else { | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(env, ast[2]) | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| env = Object.create(env) | ||
| for (let i in ast[1]) { | ||
| if (i%2) { | ||
| env[ast[1][i-1]] = EVAL(ast[1][i], env) | ||
| } | ||
| } | ||
| return EVAL(ast[2], env) | ||
| } else { // invoke list form | ||
| let el = eval_ast(ast, env), | ||
| f = el[0] | ||
| return f.apply(f, el.slice(1)) | ||
| ast[1].map((e,i) => i%2 ? env[ast[1][i-1]] = EVAL(env, ast[1][i]) : 0) | ||
| return EVAL(env, ast[2]) | ||
| } else { // invoke list form | ||
| f = EVAL(env, ast[0]) | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| return f(...el) | ||
| } | ||
| } | ||
| } | ||
| let E = Object.assign(this, { | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| }) | ||
| E = { | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| } | ||
| // Node specific | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,EVAL(JSON.parse(a[0]),E)), | ||
| writer: JSON.stringify, | ||
| terminal: 0}) | ||
| }() | ||
| eval: (...a) => a[3](0,JSON.stringify(EVAL(E, JSON.parse(a[0])))), | ||
| writer: (...a) => a[0]}) |
@@ -1,1 +0,1 @@ | ||
| for(_='(iCnCB,i(tre[t]"==if(JSON..map()))=>t in ilet typeof =Object.(...[0][1]n,";".slice(B[2] cate(,r):nn instanceof Arrayfunctioni)turn "!(){ B{!CtCdefr[i]= fne){ ,tC,r,e}let{rr);for()t%2&&(r[i[t-1]]=B); }"dotC1)[i.length-2]ifB? :B[3];{n=tC,e=n;e.apply(e,n1}}t={r?Ci),t.some((n,e"&n?i[t[e+1]]=re):C[n]=r[e],0):t?ttn:"t??i:null:t}assignhis,{"====<<++--**//n,list,mapt=>n});qui("pl").start({eval:tt[3](0,n(parse),writer:stringify,terminal:0})}()';G=/[-BC]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='reB(r,na[2]map"==)=>[0](...:tt"(tArray)),JSON.?r[n):typeof .at(-1).slice(.=> (,e[1]function){Bturn t,"r=Object.cBate(r),nn?n1) a(r,t i,i.some"&t[e+1]]=ie(r[t]=i[e],0,r} a,t,e.is(n)?"defr[n]="let(.e%2[e-1]]=a[e]0),)"do:"ifa)?3]"fnta(i,t),n)}:=ae="n?n in r]:=>{throw n+" not found"})(n}A={"====<<++--**//t,list,:ee e},BquiB("Bpl").start({eval[3](0stringify(a(Aparse,writer})';G=/[-B]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
@@ -1,1 +0,1 @@ | ||
| !function(){function n(i,r){if(!(i instanceof Array))return t(i,r);if("def"==i[0])return r[i[1]]=n(i[2],r);if("fn"==i[0])return function(...e){return n(i[2],t(i[1],r,e))};if("let"==i[0]){r=Object.create(r);for(let t in i[1])t%2&&(r[i[1][t-1]]=n(i[1][t],r));return n(i[2],r)}if("do"==i[0])return t(i.slice(1),r)[i.length-2];if("if"==i[0])return n(i[1],r)?n(i[2],r):n(i[3],r);{let n=t(i,r),e=n[0];return e.apply(e,n.slice(1))}}let t=function(t,i,r){return r?(i=Object.create(i),t.some((n,e)=>"&"==n?i[t[e+1]]=r.slice(e):(i[n]=r[e],0)),i):t instanceof Array?t.map((...t)=>n(t[0],i)):typeof ""==typeof t?t in i?i[t]:null[t]:t},i=Object.assign(this,{"=":(...n)=>n[0]===n[1],"<":(...n)=>n[0]<n[1],"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1],list:(...n)=>n,map:(...n)=>n[1].map(t=>n[0](t))});require("repl").start({eval:(...t)=>t[3](0,n(JSON.parse(t[0]),i)),writer:JSON.stringify,terminal:0})}() | ||
| function i(r,n,i){return r=Object.create(r),n.some((t,e)=>"&"==t?r[n[e+1]]=i.slice(e):(r[t]=i[e],0)),r}function a(r,n,t,e){return Array.isArray(n)?"def"==n[0]?r[n[1]]=a(r,n[2]):"let"==n[0]?(r=Object.create(r),n[1].map((t,e)=>e%2?r[n[1][e-1]]=a(r,n[1][e]):0),a(r,n[2])):"do"==n[0]?n.slice(1).map(t=>a(r,t)).at(-1):"if"==n[0]?a(r,n[1])?a(r,n[2]):a(r,n[3]):"fn"==n[0]?function(...t){return a(i(r,n[1],t),n.at(-1))}:(t=a(r,n[0]))(...e=n.slice(1).map(t=>a(r,t))):typeof ""==typeof n?n in r?r[n]:(t=>{throw n+" not found"})():n}E={"=":(...t)=>t[0]===t[1],"<":(...t)=>t[0]<t[1],"+":(...t)=>t[0]+t[1],"-":(...t)=>t[0]-t[1],"*":(...t)=>t[0]*t[1],"/":(...t)=>t[0]/t[1],list:(...t)=>t,map:(...e)=>e[1].map(t=>e[0](t))},require("repl").start({eval:(...t)=>t[3](0,JSON.stringify(a(E,JSON.parse(t[0])))),writer:(...t)=>t[0]}) |
+49
-64
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Copyright (C) 2024 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| !function() { | ||
| // 2 args: eval_ast, 3 args: env_bind | ||
| let eval_ast_or_bind = function(ast, env, exprs) { | ||
| if (exprs) { | ||
| // Return new Env with symbols in ast bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| ast.some((a,i) => a == "&" ? env[ast[i+1]] = exprs.slice(i) | ||
| : (env[a] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| // Evaluate the form/ast | ||
| return ast instanceof Array // list? | ||
| ? ast.map((...a) => EVAL(a[0], env)) // list | ||
| : (typeof ast == "string") // symbol? | ||
| ? ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : null[ast] // undefined symbol | ||
| : ast // ast unchanged | ||
| function new_env(env, ast, exprs) { | ||
| // Return new Env with symbols in ast bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| ast.some((a,i) => a == "&" ? env[ast[i+1]] = exprs.slice(i) | ||
| : (env[a] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast, f, el) { | ||
| //console.log("EVAL:", ast) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(ast[2], env) | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| if (!Array.isArray(ast)) { | ||
| // eval | ||
| if (typeof ast == "string") { | ||
| return ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : (a => {throw ast + " not found"})() // undefined symbol | ||
| } else { | ||
| return ast | ||
| } | ||
| } else { | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(env, ast[2]) | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| env = Object.create(env) | ||
| ast[1].map((e,i) => i%2 ? env[ast[1][i-1]] = EVAL(env, ast[1][i]) : 0) | ||
| return EVAL(env, ast[2]) | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| return ast.slice(1).map(v => EVAL(env, v)).at(-1) | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| return EVAL(env, ast[1]) ? EVAL(env, ast[2]) : EVAL(env, ast[3]) | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| return function(...a) { | ||
| return EVAL(ast[2], eval_ast_or_bind(ast[1], env, a)) | ||
| return EVAL(new_env(env, ast[1], a), ast.at(-1)) | ||
| } | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| env = Object.create(env) | ||
| for (let i in ast[1]) { | ||
| if (i%2) { | ||
| env[ast[1][i-1]] = EVAL(ast[1][i], env) | ||
| } | ||
| } | ||
| return EVAL(ast[2], env) | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| return eval_ast_or_bind(ast.slice(1), env)[ast.length-2] | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| if (EVAL(ast[1], env)) { | ||
| return EVAL(ast[2],env); | ||
| } else { | ||
| return EVAL(ast[3],env); | ||
| } | ||
| } else { // invoke list form | ||
| let el = eval_ast_or_bind(ast, env), | ||
| f = el[0] | ||
| return f.apply(f, el.slice(1)) | ||
| } else { // invoke list form | ||
| f = EVAL(env, ast[0]) | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| return f(...el) | ||
| } | ||
| } | ||
| } | ||
| let E = Object.assign(this, { | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "list": (...a) => a, | ||
| "map": (...a) => a[1].map(x => a[0](x)), | ||
| }) | ||
| E = { | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "list": (...a) => a, | ||
| "map": (...a) => a[1].map(x => a[0](x)), | ||
| } | ||
| // Node specific | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,EVAL(JSON.parse(a[0]),E)), | ||
| writer: JSON.stringify, | ||
| terminal: 0}) | ||
| }() | ||
| eval: (...a) => a[3](0,JSON.stringify(EVAL(E, JSON.parse(a[0])))), | ||
| writer: (...a) => a[0]}) |
@@ -1,1 +0,1 @@ | ||
| for(_='[i]Y"==X(tWnWVreUJSON.T.map(;t=t[,t)=>let {n=iWi in t))typeof f.A[2]=Object.if(t.length-1[1]n,"(...Tparse(]}else "[0],e) cUate( instanceof Arrayfunction.slice(:nXt)Uturn "n!(){ V {for(;;){!WiW ;"defe[t]=V ;"fn{f=f){V,iW,e,f};=[t,e],f}"let{ee);for()i%2&&(e[t[i-1]]=VY )2do1,) ift=V ?t:t[3];else ,f=n;!)fn1;t=,e=i(,,n1}}}i=(i {e?Wt),i.some((n,f"&Xn?t[i[f+1]]=ef):W[n]=e[f],0):i?iin(i:"Xi??tY:nullY:i}assigVhis,{"====<<++--**//n,listn,mapni=>n(i,Uadn),ARGS:process.argv3)});UquiU("Upl").start({eval:ii[3](0,n(i),writer:Tstringifyerminal:0})}()';G=/[-T-Y]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='=>FreEmapD"==C(...B[0]:Be)Fe"r)(eArray),(t,i=f[2],JSON.?t[itypeof Object..DFi.at(-1)(,Fif([1]e," .slice(function;else1)f(t,e)t=cEate(tii= "Ci)Eturn n,n){.some"&Ce[r+1]]=n:(t[e]=n[r],0)t} f,e,{for(;;){!.is(i))"Ci?i in t]:F{throw i+" not found"})():i;"deft[i]);"let.Dr%2[r-1]][r]):0doi1,-ifi)?i:{"fnassign(Be){f(n,e)},[i,t,i]);er=i!(0 in e))eB;i=e,t=n,e,}}}A={"==== << ++ -- ** //e,list,D:BFrr))},EquiE("Epl").start({eval[3](0stringify(f(Aparse)))writer})';G=/[-B-F]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
@@ -1,1 +0,1 @@ | ||
| !function(){function n(t,e){for(;;){if(!(t instanceof Array))return i(t,e);if("def"==t[0])return e[t[1]]=n(t[2],e);if("fn"==t[0]){let f=function(...f){return n(t[2],i(t[1],e,f))};return f.A=[t[2],e,t[1]],f}if("let"==t[0]){e=Object.create(e);for(let i in t[1])i%2&&(e[t[1][i-1]]=n(t[1][i],e));t=t[2]}else if("do"==t[0]){let n=i(t.slice(1,t.length-1),e);t=t[t.length-1]}else if("if"==t[0])t=n(t[1],e)?t[2]:t[3];else{let n=i(t,e),f=n[0];if(!f.A)return f(...n.slice(1));t=f.A[0],e=i(f.A[2],f.A[1],n.slice(1))}}}let i=function(i,t,e){return e?(t=Object.create(t),i.some((n,f)=>"&"==n?t[i[f+1]]=e.slice(f):(t[n]=e[f],0)),t):i instanceof Array?i.map((...i)=>n(i[0],t)):typeof ""==typeof i?i in t?t[i]:null[i]:i},t=Object.assign(this,{"=":(...n)=>n[0]===n[1],"<":(...n)=>n[0]<n[1],"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1],list:(...n)=>n,map:(...n)=>n[1].map(i=>n[0](i)),read:(...n)=>JSON.parse(n[0]),ARGS:process.argv.slice(3)});require("repl").start({eval:(...i)=>i[3](0,n(JSON.parse(i[0]),t)),writer:JSON.stringify,terminal:0})}() | ||
| function n(t,i,n){return t=Object.create(t),i.some((e,r)=>"&"==e?t[i[r+1]]=n.slice(r):(t[e]=n[r],0)),t}function f(t,i,e,r){for(;;){if(!Array.isArray(i))return typeof ""==typeof i?i in t?t[i]:(e=>{throw i+" not found"})():i;if("def"==i[0])return t[i[1]]=f(t,i[2]);if("let"==i[0])t=Object.create(t),i[1].map((e,r)=>r%2?t[i[1][r-1]]=f(t,i[1][r]):0),i=i.at(-1);else if("do"==i[0])i.slice(1,-1).map(e=>f(t,e)),i=i.at(-1);else if("if"==i[0])i=f(t,i[1])?i[2]:i.at(-1);else{if("fn"==i[0])return Object.assign(function(...e){return f(n(t,i[1],e),i.at(-1))},[i[2],t,i[1]]);if(e=f(t,i[0]),r=i.slice(1).map(e=>f(t,e)),!(0 in e))return e(...r);i=e[0],t=n(e[1],e[2],r)}}}E={"=":(...e)=>e[0]===e[1],"<":(...e)=>e[0]<e[1],"+":(...e)=>e[0]+e[1],"-":(...e)=>e[0]-e[1],"*":(...e)=>e[0]*e[1],"/":(...e)=>e[0]/e[1],list:(...e)=>e,map:(...r)=>r[1].map(e=>r[0](e))},require("repl").start({eval:(...e)=>e[3](0,JSON.stringify(f(E,JSON.parse(e[0])))),writer:(...e)=>e[0]}) |
+54
-74
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Copyright (C) 2024 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| !function() { | ||
| // 2 args: eval_ast, 3 args: env_bind | ||
| let eval_ast_or_bind = function(ast, env, exprs) { | ||
| if (exprs) { | ||
| // Return new Env with symbols in ast bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| ast.some((a,i) => a == "&" ? env[ast[i+1]] = exprs.slice(i) | ||
| : (env[a] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| // Evaluate the form/ast | ||
| return ast instanceof Array // list? | ||
| ? ast.map((...a) => EVAL(a[0], env)) // list | ||
| : (typeof ast == "string") // symbol? | ||
| ? ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : null[ast] // undefined symbol | ||
| : ast // ast unchanged | ||
| function new_env(env, ast, exprs) { | ||
| // Return new Env with symbols in ast bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| ast.some((a,i) => a == "&" ? env[ast[i+1]] = exprs.slice(i) | ||
| : (env[a] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast, f, el) { | ||
| while (true) { | ||
| //console.log("EVAL:", ast) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(ast[2], env) | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| let f = function(...a) { | ||
| return EVAL(ast[2], eval_ast_or_bind(ast[1], env, a)) | ||
| } | ||
| f.A = [ast[2], env, ast[1]] | ||
| return f | ||
| } | ||
| // TCO cases | ||
| if (ast[0] == "let") { // new environment with bindings | ||
| if (!Array.isArray(ast)) { | ||
| // eval | ||
| if (typeof ast == "string") { | ||
| return ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : (a => {throw ast + " not found"})() // undefined symbol | ||
| } else { | ||
| return ast | ||
| } | ||
| } else { | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(env, ast[2]) | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| env = Object.create(env) | ||
| for (let i in ast[1]) { | ||
| if (i%2) { | ||
| env[ast[1][i-1]] = EVAL(ast[1][i], env) | ||
| } | ||
| } | ||
| ast = ast[2] | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| let el = eval_ast_or_bind(ast.slice(1,ast.length-1), env) | ||
| ast = ast[ast.length-1] | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(ast[1], env) ? ast[2] : ast[3] | ||
| } else { // invoke list form | ||
| let el = eval_ast_or_bind(ast, env), | ||
| f = el[0] | ||
| if (f.A) { | ||
| ast = f.A[0] | ||
| env = eval_ast_or_bind(f.A[2], f.A[1], el.slice(1)) | ||
| ast[1].map((e,i) => i%2 ? env[ast[1][i-1]] = EVAL(env, ast[1][i]) : 0) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| ast.slice(1,-1).map(v => EVAL(env, v)) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(env, ast[1]) ? ast[2] : ast.at(-1) | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| return Object.assign(function(...a) { | ||
| return EVAL(new_env(env, ast[1], a), ast.at(-1)) | ||
| }, [ast[2], env, ast[1]]) | ||
| } else { // invoke list form | ||
| f = EVAL(env, ast[0]) | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| if (0 in f) { | ||
| ast = f[0] | ||
| env = new_env(f[1], f[2], el) | ||
| } else { | ||
| return f(...el.slice(1)) | ||
| return f(...el) | ||
| } | ||
| } | ||
| } | ||
@@ -70,23 +57,16 @@ } | ||
| let E = Object.assign(this, { | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "list": (...a) => a, | ||
| "map": (...a) => a[1].map(x => a[0](x)), | ||
| E = { | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "list": (...a) => a, | ||
| "map": (...a) => a[1].map(x => a[0](x)), | ||
| } | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "ARGS": process.argv.slice(3) | ||
| }) | ||
| // Node specific | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,EVAL(JSON.parse(a[0]),E)), | ||
| writer: JSON.stringify, | ||
| terminal: 0}) | ||
| }() | ||
| eval: (...a) => a[3](0,JSON.stringify(EVAL(E, JSON.parse(a[0])))), | ||
| writer: (...a) => a[0]}) |
@@ -1,1 +0,1 @@ | ||
| for(_=',iK,t7(i6=n65;i=4[e]E"==Dif(Ce(B.slicBZnZ1))Y)=>X(...WWeXn(VJSON.UreTlet {n=Bi{eval:e in i:WnX)K)C"}else typeof t.A=Object.[0],"utf8")TquiT("i.length-1[1]n,"[2],r)VeK)cTatB instanceof ArrayfunctionUparsBprocess.argvDi)fs").TadFileSync(Tturn "n!(){ n6{for(;;){C!6))Bi;defr[i]5;`i;fn{t=Wt){n6,Bi,r7))};=[i,rK]7}let{r r);for()e%2&&(r[i[e-1]]5E)4idoZ1,)4i[]ifi5?i:i[3];else7=n;C!)tWY4,r=B,,Y}}}e=(eK{r?6 i),e.somB(n7X"&Dn?i[e[t+1]]=rZt):6[n]=r[t],0):e?e.map():"De??iE:nullE:e}Kassign(this,,"====<<++--**//n,Tadn),slurpn,load:Ve,ARGS:Z3)});?i.load():Tpl").start(WeXe[3](0,n(e),writer:Ustringify7erminal:0})}()';G=/[-T-ZB-E4-7K]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='[1]CeC,B[0]Z"==Y,r)XJSON.WArrayVreU(i,tT=aTif((...:e)=>{evala(A,?i[ttypeof Object.),t.at(-1)((eX=>eZ"[2]UquiU("B";"function;else.slice( 1).map(e=>a(i,e)Wparse(process.argvi=cUate(itt= "YtZ)fs").UadFileSync(Uturn sT,s){.some"&Ye[r+1]]=s r):(i[e]=s[r],0)i} aT,eX{for(;;){!V.isV(t))"Yt?t in i]:(e=>{throw t+" not found"})():tdefi[tC])`tCfnassign(e){a(sTC,e)},[t,i,tC])letC.mapr%2C[r-1]]C[r]):0dot 1,-iftC)?t:{eZr=t !(0 in e))er);t=,i=s(BeX}}}A="====<<++--**//Bliste,Uadslurp,"utf8"argv: 3)},?))):Upl").start(e[3](0,Wstringify()))writer})';G=/[-T-ZBC]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
@@ -1,1 +0,1 @@ | ||
| !function(){function n(i,r){for(;;){if(!(i instanceof Array))return e(i,r);if("def"==i[0])return r[i[1]]=n(i[2],r);if("`"==i[0])return i[1];if("fn"==i[0]){let t=function(...t){return n(i[2],e(i[1],r,t))};return t.A=[i[2],r,i[1]],t}if("let"==i[0]){r=Object.create(r);for(let e in i[1])e%2&&(r[i[1][e-1]]=n(i[1][e],r));i=i[2]}else if("do"==i[0]){let n=e(i.slice(1,i.length-1),r);i=i[i.length-1]}else if("if"==i[0])i=n(i[1],r)?i[2]:i[3];else{let n=e(i,r),t=n[0];if(!t.A)return t(...n.slice(1));i=t.A[0],r=e(t.A[2],t.A[1],n.slice(1))}}}let e=function(e,i,r){return r?(i=Object.create(i),e.some((n,t)=>"&"==n?i[e[t+1]]=r.slice(t):(i[n]=r[t],0)),i):e instanceof Array?e.map((...e)=>n(e[0],i)):typeof ""==typeof e?e in i?i[e]:null[e]:e},i=Object.assign(this,{eval:(...e)=>n(e[0],i),"=":(...n)=>n[0]===n[1],"<":(...n)=>n[0]<n[1],"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1],read:(...n)=>JSON.parse(n[0]),slurp:(...n)=>require("fs").readFileSync(n[0],"utf8"),load:(...e)=>n(JSON.parse(require("fs").readFileSync(e[0],"utf8")),i),ARGS:process.argv.slice(3)});process.argv[2]?i.load(process.argv[2]):require("repl").start({eval:(...e)=>e[3](0,n(JSON.parse(e[0]),i)),writer:JSON.stringify,terminal:0})}() | ||
| function s(i,t,s){return i=Object.create(i),t.some((e,r)=>"&"==e?i[t[r+1]]=s.slice(r):(i[e]=s[r],0)),i}function a(i,t,e,r){for(;;){if(!Array.isArray(t))return typeof ""==typeof t?t in i?i[t]:(e=>{throw t+" not found"})():t;if("def"==t[0])return i[t[1]]=a(i,t[2]);if("`"==t[0])return t[1];if("fn"==t[0])return Object.assign(function(...e){return a(s(i,t[1],e),t.at(-1))},[t[2],i,t[1]]);if("let"==t[0])i=Object.create(i),t[1].map((e,r)=>r%2?i[t[1][r-1]]=a(i,t[1][r]):0),t=t.at(-1);else if("do"==t[0])t.slice(1,-1).map(e=>a(i,e)),t=t.at(-1);else if("if"==t[0])t=a(i,t[1])?t[2]:t.at(-1);else{if(e=a(i,t[0]),r=t.slice(1).map(e=>a(i,e)),!(0 in e))return e(...r);t=e[0],i=s(e[1],e[2],r)}}}E={eval:(...e)=>a(E,e[0]),"=":(...e)=>e[0]===e[1],"<":(...e)=>e[0]<e[1],"+":(...e)=>e[0]+e[1],"-":(...e)=>e[0]-e[1],"*":(...e)=>e[0]*e[1],"/":(...e)=>e[0]/e[1],list:(...e)=>e,read:(...e)=>JSON.parse(e[0]),slurp:(...e)=>require("fs").readFileSync(e[0],"utf8"),argv:process.argv.slice(3)},process.argv[2]?a(E,JSON.parse(require("fs").readFileSync(process.argv[2]))):require("repl").start({eval:(...e)=>e[3](0,JSON.stringify(a(E,JSON.parse(e[0])))),writer:(...e)=>e[0]}) |
+64
-79
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Copyright (C) 2024 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| !function() { | ||
| // 2 args: eval_ast, 3 args: env_bind | ||
| let eval_ast_or_bind = function(ast, env, exprs) { | ||
| if (exprs) { | ||
| // Return new Env with symbols in ast bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| ast.some((a,i) => a == "&" ? env[ast[i+1]] = exprs.slice(i) | ||
| : (env[a] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| // Evaluate the form/ast | ||
| return ast instanceof Array // list? | ||
| ? ast.map((...a) => EVAL(a[0], env)) // list | ||
| : (typeof ast == "string") // symbol? | ||
| ? ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : null[ast] // undefined symbol | ||
| : ast // ast unchanged | ||
| function new_env(env, binds, exprs) { | ||
| // Return new Env with symbols in binds bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| binds.some((b,i) => b == "&" ? env[binds[i+1]] = exprs.slice(i) | ||
| : (env[b] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast, f, el) { | ||
| while (true) { | ||
| //console.log("EVAL:", ast) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(ast[2], env) | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| if (!Array.isArray(ast)) { | ||
| // eval | ||
| if (typeof ast == "string") { | ||
| return ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : (a => {throw ast + " not found"})() // undefined symbol | ||
| } else { | ||
| return ast | ||
| } | ||
| } else { | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(env, ast[2]) | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| return ast[1] | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| let f = function(...a) { | ||
| return EVAL(ast[2], eval_ast_or_bind(ast[1], env, a)) | ||
| } | ||
| f.A = [ast[2], env, ast[1]] | ||
| return f | ||
| } | ||
| // TCO cases | ||
| if (ast[0] == "let") { // new environment with bindings | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| return Object.assign(function(...a) { | ||
| return EVAL(new_env(env, ast[1], a), ast.at(-1)) | ||
| }, [ast[2], env, ast[1]]) | ||
| // TCO cases | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| env = Object.create(env) | ||
| for (let i in ast[1]) { | ||
| if (i%2) { | ||
| env[ast[1][i-1]] = EVAL(ast[1][i], env) | ||
| } | ||
| } | ||
| ast = ast[2] | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| let el = eval_ast_or_bind(ast.slice(1,ast.length-1), env) | ||
| ast = ast[ast.length-1] | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(ast[1], env) ? ast[2] : ast[3] | ||
| } else { // invoke list form | ||
| let el = eval_ast_or_bind(ast, env), | ||
| f = el[0] | ||
| if (f.A) { | ||
| ast = f.A[0] | ||
| env = eval_ast_or_bind(f.A[2], f.A[1], el.slice(1)) | ||
| ast[1].map((e,i) => i%2 ? env[ast[1][i-1]] = EVAL(env, ast[1][i]) : 0) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| ast.slice(1,-1).map(v => EVAL(env, v)) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(env, ast[1]) ? ast[2] : ast.at(-1) | ||
| } else { // invoke list form | ||
| f = EVAL(env, ast[0]) | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| if (0 in f) { | ||
| ast = f[0] | ||
| env = new_env(f[1], f[2], el) | ||
| } else { | ||
| return f(...el.slice(1)) | ||
| return f(...el) | ||
| } | ||
| } | ||
| } | ||
@@ -72,32 +60,29 @@ } | ||
| let E = Object.assign(this, { | ||
| "eval": (...a) => EVAL(a[0], E), | ||
| E = { | ||
| "eval": (...a) => EVAL(E, a[0]), | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| //"list": (...a) => a, | ||
| //"map": (...a) => a[1].map(x => a[0](x)), | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "list": (...a) => a, | ||
| ///"map": (...a) => a[1].map(x => a[0](x)), | ||
| ///"load": (...a) => EVAL(E, JSON.parse(require("fs").readFileSync(a[0],"utf8"))), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "load": (...a) => EVAL(JSON.parse(require("fs").readFileSync(a[0],"utf8")),E), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "ARGS": process.argv.slice(3) | ||
| }) | ||
| "argv": process.argv.slice(3) | ||
| } | ||
| // Node specific | ||
| if (process.argv[2]) { | ||
| E.load(process.argv[2]) | ||
| EVAL(E,JSON.parse(require("fs").readFileSync(process.argv[2]))) | ||
| } else { | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,EVAL(JSON.parse(a[0]),E)), | ||
| writer: JSON.stringify, | ||
| terminal: 0}) | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,JSON.stringify(EVAL(E, JSON.parse(a[0])))), | ||
| writer: (...a) => a[0]}) | ||
| } | ||
| }() |
@@ -1,1 +0,1 @@ | ||
| for(_='[1]~n~Z,tYe(X;i=W[e]Vif(U)=>T(...Q:QnTP[0]MPnML"LK=nIQeTn(HJSON.EreD,r)CCYIMBeval in )),iinstanceof ArrayU"}else typeof t.A=Object.let (iM,"utf8")DquiD("i.length-1Z,"HeM)[2]cDatX{n=e functionEparsXprocess.argvfs").DadFileSync(.slicXDturn "==iM) 1)B[Z];!(){ nC{for(;;){U!eC;defr[i~]IC;`i~;.-2n?nM[Z]I:t}.t.apply(nM,n2}fn{t=Qt){n,e~,rY};=[i,r~]Y}let{rr);for(ei~)e%2&&(r[i~[e-1]]I~V,rWido 1,)CWi[]ifiI~C?i:i[3];else B;U!)tQn1WM,r=X,~,n1}}}e=(eC{r?i),e.somX(nYT"&"=I?i[e[t+1]]=rt):[n]=r[t],0):e?e.map():""==e?ei?iV:nullV:e}assign(this,{js:,:,"=K===<K<+K+-K-*K*/K/ZsaLZ,DadPnM),slurpPn,load:He)),ARGS:3)});?i.load():Dpl").start({:QeTe[3](0,n(eM),writer:EstringifyYerminal:0})}()';G=/[^ -AFGJNORS[-}]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='if(YY"X[rW[1]VeV,U"==T,r)R;XQ))P),M1).map(e=>a(i,e)ML.slice(Kr=tKLIt.at(-1)HH;elseGt=G XEJSON.DArrayCreB(i,t=a[0]rWV]a(A,eval(... in ?i[tetypeof Object.throw((eR=>BquiB("[2]U":e)=>"functionTt) assign(Dparse(Bturn process.argvi=cBate(iMtfs").BadFileSync( IF=, s,s){.some"&TeW+1]]=sKr):(i[e]=sW],0)Mi} a,eR{for(;;){Y!C.isC(tP"Tt?ti]:A.(t+" not found"):tQdefi[tV])Q`tVQ.-2r?=r:FQ.F.apply(r,rK2PQfne){a(sV,eMH)},[t,i,tV])Qlet V.mapr%2VW-1]]VW]):0MEdo tK1,-LEif tV)?t:G{YeMI!(0ePer);t=,i=s(UeR}}}A=this,{js:,M"====<<++--**//Uliste,{ },BadMslurp,"utf8"Margv:K3)}M?P):Bpl").start({e[3](0,Dstringify(P)Mwriter})';G=/[^ -AFJNOS[-}]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
@@ -1,1 +0,1 @@ | ||
| !function(){function n(i,r){for(;;){if(!(i instanceof Array))return e(i,r);if("def"==i[0])return r[i[1]]=n(i[2],r);if("`"==i[0])return i[1];if(".-"==i[0]){let n=e(i.slice(1),r),t=n[0][n[1]];return 2 in n?n[0][n[1]]=n[2]:t}if("."==i[0]){let n=e(i.slice(1),r),t=n[0][n[1]];return t.apply(n[0],n.slice(2))}if("fn"==i[0]){let t=function(...t){return n(i[2],e(i[1],r,t))};return t.A=[i[2],r,i[1]],t}if("let"==i[0]){r=Object.create(r);for(let e in i[1])e%2&&(r[i[1][e-1]]=n(i[1][e],r));i=i[2]}else if("do"==i[0]){let n=e(i.slice(1,i.length-1),r);i=i[i.length-1]}else if("if"==i[0])i=n(i[1],r)?i[2]:i[3];else{let n=e(i,r),t=n[0];if(!t.A)return t(...n.slice(1));i=t.A[0],r=e(t.A[2],t.A[1],n.slice(1))}}}let e=function(e,i,r){return r?(i=Object.create(i),e.some((n,t)=>"&"==n?i[e[t+1]]=r.slice(t):(i[n]=r[t],0)),i):e instanceof Array?e.map((...e)=>n(e[0],i)):typeof ""==typeof e?e in i?i[e]:null[e]:e},i=Object.assign(this,{js:eval,eval:(...e)=>n(e[0],i),"=":(...n)=>n[0]===n[1],"<":(...n)=>n[0]<n[1],"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1],isa:(...n)=>n[0]instanceof n[1],read:(...n)=>JSON.parse(n[0]),slurp:(...n)=>require("fs").readFileSync(n[0],"utf8"),load:(...e)=>n(JSON.parse(require("fs").readFileSync(e[0],"utf8")),i),ARGS:process.argv.slice(3)});process.argv[2]?i.load(process.argv[2]):require("repl").start({eval:(...e)=>e[3](0,n(JSON.parse(e[0]),i)),writer:JSON.stringify,terminal:0})}() | ||
| function s(i,t,s){return i=Object.create(i),t.some((e,r)=>"&"==e?i[t[r+1]]=s.slice(r):(i[e]=s[r],0)),i}function a(i,t,e,r){for(;;){if(!Array.isArray(t))return typeof ""==typeof t?t in i?i[t]:E.throw(t+" not found"):t;if("def"==t[0])return i[t[1]]=a(i,t[2]);if("`"==t[0])return t[1];if(".-"==t[0])return r=t.slice(1).map(e=>a(i,e)),x=r[0][r[1]],2 in r?r[0][r[1]]=r[2]:x;if("."==t[0])return r=t.slice(1).map(e=>a(i,e)),x=r[0][r[1]],x.apply(r[0],r.slice(2));if("fn"==t[0])return Object.assign(function(...e){return a(s(i,t[1],e),t.at(-1))},[t[2],i,t[1]]);if("let"==t[0])i=Object.create(i),t[1].map((e,r)=>r%2?i[t[1][r-1]]=a(i,t[1][r]):0),t=t.at(-1);else if("do"==t[0])t.slice(1,-1).map(e=>a(i,e)),t=t.at(-1);else if("if"==t[0])t=a(i,t[1])?t[2]:t.at(-1);else{if(e=a(i,t[0]),r=t.slice(1).map(e=>a(i,e)),!(0 in e))return e(...r);t=e[0],i=s(e[1],e[2],r)}}}E=Object.assign(this,{js:eval,eval:(...e)=>a(E,e[0]),"=":(...e)=>e[0]===e[1],"<":(...e)=>e[0]<e[1],"+":(...e)=>e[0]+e[1],"-":(...e)=>e[0]-e[1],"*":(...e)=>e[0]*e[1],"/":(...e)=>e[0]/e[1],list:(...e)=>e,throw:(...e)=>{throw e[0]},read:(...e)=>JSON.parse(e[0]),slurp:(...e)=>require("fs").readFileSync(e[0],"utf8"),argv:process.argv.slice(3)}),process.argv[2]?a(E,JSON.parse(require("fs").readFileSync(process.argv[2]))):require("repl").start({eval:(...e)=>e[3](0,JSON.stringify(a(E,JSON.parse(e[0])))),writer:(...e)=>e[0]}) |
+77
-86
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Copyright (C) 2024 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
@@ -7,71 +7,61 @@ | ||
| // 2 args: eval_ast, 3 args: env_bind | ||
| let eval_ast_or_bind = function(ast, env, exprs) { | ||
| if (exprs) { | ||
| // Return new Env with symbols in ast bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| ast.some((a,i) => a == "&" ? env[ast[i+1]] = exprs.slice(i) | ||
| : (env[a] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| // Evaluate the form/ast | ||
| return ast instanceof Array // list? | ||
| ? ast.map((...a) => EVAL(a[0], env)) // list | ||
| : (typeof ast == "string") // symbol? | ||
| ? ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : null[ast] // undefined symbol | ||
| : ast // ast unchanged | ||
| function new_env(env, binds, exprs) { | ||
| // Return new Env with symbols in binds bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| binds.some((b,i) => b == "&" ? env[binds[i+1]] = exprs.slice(i) | ||
| : (env[b] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast, f, el) { | ||
| while (true) { | ||
| //console.log("EVAL:", ast) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(ast[2], env) | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| if (!Array.isArray(ast)) { | ||
| // eval | ||
| if (typeof ast == "string") { | ||
| return ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : E.throw(ast + " not found") // undefined symbol | ||
| } else { | ||
| return ast | ||
| } | ||
| } else { | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(env, ast[2]) | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| return ast[1] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return 2 in el ? el[0][el[1]] = el[2] : x | ||
| } else if (ast[0] == ".") { // call object method | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".") { // call object method | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return x.apply(el[0], el.slice(2)) | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| let f = function(...a) { | ||
| return EVAL(ast[2], eval_ast_or_bind(ast[1], env, a)) | ||
| } | ||
| f.A = [ast[2], env, ast[1]] | ||
| return f | ||
| } | ||
| // TCO cases | ||
| if (ast[0] == "let") { // new environment with bindings | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| return Object.assign(function(...a) { | ||
| return EVAL(new_env(env, ast[1], a), ast.at(-1)) | ||
| }, [ast[2], env, ast[1]]) | ||
| // TCO cases | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| env = Object.create(env) | ||
| for (let i in ast[1]) { | ||
| if (i%2) { | ||
| env[ast[1][i-1]] = EVAL(ast[1][i], env) | ||
| } | ||
| } | ||
| ast = ast[2] | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| let el = eval_ast_or_bind(ast.slice(1,ast.length-1), env) | ||
| ast = ast[ast.length-1] | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(ast[1], env) ? ast[2] : ast[3] | ||
| } else { // invoke list form | ||
| let el = eval_ast_or_bind(ast, env), | ||
| f = el[0] | ||
| if (f.A) { | ||
| ast = f.A[0] | ||
| env = eval_ast_or_bind(f.A[2], f.A[1], el.slice(1)) | ||
| ast[1].map((e,i) => i%2 ? env[ast[1][i-1]] = EVAL(env, ast[1][i]) : 0) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| ast.slice(1,-1).map(v => EVAL(env, v)) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(env, ast[1]) ? ast[2] : ast.at(-1) | ||
| } else { // invoke list form | ||
| f = EVAL(env, ast[0]) | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| if (0 in f) { | ||
| ast = f[0] | ||
| env = new_env(f[1], f[2], el) | ||
| } else { | ||
| return f(...el.slice(1)) | ||
| return f(...el) | ||
| } | ||
| } | ||
| } | ||
@@ -81,26 +71,28 @@ } | ||
| let E = Object.assign(this, { | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(a[0], E), | ||
| E = Object.assign(this, { | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(E, a[0]), | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "isa": (...a) => a[0] instanceof a[1], | ||
| // new can use Reflect.construct | ||
| //"new": (...a) => new (a[0].bind(...a)), | ||
| // delete can use Reflect.deleteProperty | ||
| //"del": (...a) => delete a[0][a[1]], | ||
| //"list": (...a) => a, | ||
| //"map": (...a) => a[1].map(x => a[0](x)), | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "list": (...a) => a, | ||
| ///"map": (...a) => a[1].map(x => a[0](x)), | ||
| "throw": (...a) => { throw(a[0]) }, | ||
| /// isa can use isPrototypeOf | ||
| ///"isa": (...a) => a[0] instanceof a[1], | ||
| /// new can use Reflect.construct | ||
| ///"new": (...a) => new (a[0].bind(...a)), | ||
| /// delete can use Reflect.deleteProperty | ||
| ///"del": (...a) => delete a[0][a[1]], | ||
| ///"load": (...a) => EVAL(E, JSON.parse(require("fs").readFileSync(a[0],"utf8"))), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "load": (...a) => EVAL(JSON.parse(require("fs").readFileSync(a[0],"utf8")),E), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "ARGS": process.argv.slice(3) | ||
| "argv": process.argv.slice(3) | ||
| }) | ||
@@ -110,10 +102,9 @@ | ||
| if (process.argv[2]) { | ||
| E.load(process.argv[2]) | ||
| return EVAL(E,JSON.parse(require("fs").readFileSync(process.argv[2]))) | ||
| } else { | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,EVAL(JSON.parse(a[0]),E)), | ||
| writer: JSON.stringify, | ||
| terminal: 0}) | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,JSON.stringify(EVAL(E, JSON.parse(a[0])))), | ||
| writer: (...a) => a[0]}) | ||
| } | ||
| }() |
@@ -1,1 +0,1 @@ | ||
| for(_='[2]$r$#,nI]=Hr=L,tKinQ){P[1]_n_,^"==7i(r6))5let 4[0]Ee(D{4n=C.slicDB7rE)ZZC6B1Y(...nXXB15;W),VK)UnETU,e=TJSON.ree.Aif(eval Q for([nr_"}else typeof qui("=Object.:X)=>"Tr.length-1^"Qstanceof Array turn !(r 56U;catDparsDprocess.argvfunctionfs").adFileSync(T,"utf8")Y)_];!(P n(n,eP;n &&TQ e&&eE].M;)n=eE]Wn} DrU{;;PLn(rU,defZt[HD#U;~ZCDU;n.M=1I}`Z;.-2n?T_Hn$:e}.e.apply(TIB25}fnZCXPD#,i(KI5};n.A=[#K,]I}letZ{tt);4n)n%2&&(t[-1]HD]U);L#doY,)U;Lr[]ifZLDU?#:r[3];elseC6;!)eWLEK=i($,_IB15}}}4i=(n,i,rPr?(iiVn.somD(eU=>"&7e?i[t+1]HrBt):(i[eHr[t],0)Vi):n ?n.map(X)=>DT,i5:"7n?ni?i]:null]:n},rassign(this,{js:,DT,rV"====<<++--**//^isaT^adTVslurp,loadDVrVARGS:B3)});$?r.load($):pl").start({n[3](0,DTVr)Vwriter:strQgifyKermQal:0})}()';G=/[-T-ZB-E4-7^_PQKLHI#$]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='[rY[1]XeX,W"==V,r)U),T))R1).map(e=>a(i,eR,Q.slice(Pr=tPQLJSON.K;elseIArrayHreG(i,tE=aEDif(C[0]BrBYX]a(A,eval in ?i[teBtypeof Object.throwt.at(-1)((eU=>(...GquiG("[2]W":e)=>"functionVtB)Kparse(;C" Gturn process.argvi=cGate(iTtassign(fs").GadFileSync(I CLF=, sE,s){.some"&VeY+1]]=sPr):(i[e]=sY],0R,i} aE,eU{for(;;){C!H.isH(tR"Vt?ti]:A.(t+" not found"):t defi[tX]D) ~aEXT{M:1}) `tX .-2r?=r:F .F.apply(rB,rP2R fne){a(sEX,eT)},[t,i,tX]) letX.mapr%2XY-1]]DXY]):0Tt="dotP1,-Qt="iftDX)?t:(eDBR.M)t=etP1RI{CL!(0eRer);t=,i=s(WeU}}}A=this,{js:,T"====<<++--**//Wliste,{ },GadTslurp,"utf8"Targv:P3)}T?R):Gpl").start({e[3](0,Kstringify(RR,writer})';G=/[^ -AFJM-OS[-~]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
@@ -1,1 +0,1 @@ | ||
| !function(){function n(n,e){for(;n instanceof Array&&n[0]in e&&e[n[0]].M;)n=e[n[0]](...n.slice(1));return n}function e(r,t){for(;;){if(!(r instanceof Array))return i(r,t);if(r=n(r,t),!(r instanceof Array))return i(r,t);if("def"==r[0])return t[r[1]]=e(r[2],t);if("~"==r[0]){let n=e(r[1],t);return n.M=1,n}if("`"==r[0])return r[1];if(".-"==r[0]){let n=i(r.slice(1),t),e=n[0][n[1]];return 2 in n?n[0][n[1]]=n[2]:e}if("."==r[0]){let n=i(r.slice(1),t),e=n[0][n[1]];return e.apply(n[0],n.slice(2))}if("fn"==r[0]){let n=function(...n){return e(r[2],i(r[1],t,n))};return n.A=[r[2],t,r[1]],n}if("let"==r[0]){t=Object.create(t);for(let n in r[1])n%2&&(t[r[1][n-1]]=e(r[1][n],t));r=r[2]}else if("do"==r[0]){let n=i(r.slice(1,r.length-1),t);r=r[r.length-1]}else if("if"==r[0])r=e(r[1],t)?r[2]:r[3];else{let n=i(r,t),e=n[0];if(!e.A)return e(...n.slice(1));r=e.A[0],t=i(e.A[2],e.A[1],n.slice(1))}}}let i=function(n,i,r){return r?(i=Object.create(i),n.some((e,t)=>"&"==e?i[n[t+1]]=r.slice(t):(i[e]=r[t],0)),i):n instanceof Array?n.map((...n)=>e(n[0],i)):typeof ""==typeof n?n in i?i[n]:null[n]:n},r=Object.assign(this,{js:eval,eval:(...n)=>e(n[0],r),"=":(...n)=>n[0]===n[1],"<":(...n)=>n[0]<n[1],"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1],isa:(...n)=>n[0]instanceof n[1],read:(...n)=>JSON.parse(n[0]),slurp:(...n)=>require("fs").readFileSync(n[0],"utf8"),load:(...n)=>e(JSON.parse(require("fs").readFileSync(n[0],"utf8")),r),ARGS:process.argv.slice(3)});process.argv[2]?r.load(process.argv[2]):require("repl").start({eval:(...n)=>n[3](0,e(JSON.parse(n[0]),r)),writer:JSON.stringify,terminal:0})}() | ||
| function s(i,t,s){return i=Object.create(i),t.some((e,r)=>"&"==e?i[t[r+1]]=s.slice(r):(i[e]=s[r],0)),i}function a(i,t,e,r){for(;;){if(!Array.isArray(t))return typeof ""==typeof t?t in i?i[t]:E.throw(t+" not found"):t;if("def"==t[0])return i[t[1]]=a(i,t[2]);if("~"==t[0])return Object.assign(a(i,t[1]),{M:1});if("`"==t[0])return t[1];if(".-"==t[0])return r=t.slice(1).map(e=>a(i,e)),x=r[0][r[1]],2 in r?r[0][r[1]]=r[2]:x;if("."==t[0])return r=t.slice(1).map(e=>a(i,e)),x=r[0][r[1]],x.apply(r[0],r.slice(2));if("fn"==t[0])return Object.assign(function(...e){return a(s(i,t[1],e),t.at(-1))},[t[2],i,t[1]]);if("let"==t[0])i=Object.create(i),t[1].map((e,r)=>r%2?i[t[1][r-1]]=a(i,t[1][r]):0),t=t.at(-1);else if("do"==t[0])t.slice(1,-1).map(e=>a(i,e)),t=t.at(-1);else if("if"==t[0])t=a(i,t[1])?t[2]:t.at(-1);else if((e=a(i,t[0])).M)t=e(...t.slice(1));else{if(r=t.slice(1).map(e=>a(i,e)),!(0 in e))return e(...r);t=e[0],i=s(e[1],e[2],r)}}}E=Object.assign(this,{js:eval,eval:(...e)=>a(E,e[0]),"=":(...e)=>e[0]===e[1],"<":(...e)=>e[0]<e[1],"+":(...e)=>e[0]+e[1],"-":(...e)=>e[0]-e[1],"*":(...e)=>e[0]*e[1],"/":(...e)=>e[0]/e[1],list:(...e)=>e,throw:(...e)=>{throw e[0]},read:(...e)=>JSON.parse(e[0]),slurp:(...e)=>require("fs").readFileSync(e[0],"utf8"),argv:process.argv.slice(3)}),process.argv[2]?a(E,JSON.parse(require("fs").readFileSync(process.argv[2]))):require("repl").start({eval:(...e)=>e[3](0,JSON.stringify(a(E,JSON.parse(e[0])))),writer:(...e)=>e[0]}) |
+87
-104
@@ -1,92 +0,72 @@ | ||
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| /// miniMAL | ||
| /// Copyright (C) 2024 Joel Martin | ||
| /// Licensed under MPL 2.0 | ||
| !function() { | ||
| // 2 args: eval_ast, 3 args: env_bind | ||
| let eval_ast_or_bind = function(ast, env, exprs) { | ||
| if (exprs) { | ||
| // Return new Env with symbols in ast bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| ast.some((a,i) => a == "&" ? env[ast[i+1]] = exprs.slice(i) | ||
| : (env[a] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| // Evaluate the form/ast | ||
| return ast instanceof Array // list? | ||
| ? ast.map((...a) => EVAL(a[0], env)) // list | ||
| : (typeof ast == "string") // symbol? | ||
| ? ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : null[ast] // undefined symbol | ||
| : ast // ast unchanged | ||
| function new_env(env, binds, exprs) { | ||
| // Return new Env with symbols in binds bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| binds.some((b,i) => b == "&" ? env[binds[i+1]] = exprs.slice(i) | ||
| : (env[b] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| function macroexpand(ast, env) { | ||
| while (ast instanceof Array | ||
| && ast[0] in env | ||
| && env[ast[0]].M) { | ||
| ast = env[ast[0]](...ast.slice(1)) | ||
| } | ||
| return ast | ||
| } | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast, f, el) { | ||
| while (true) { | ||
| //console.log("EVAL:", ast) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| // apply | ||
| ast = macroexpand(ast, env) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(ast[2], env) | ||
| } else if (ast[0] == "~") { // mark as macro | ||
| let f = EVAL(ast[1], env) // eval regular function | ||
| f.M = 1 // mark as macro | ||
| return f | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| if (!Array.isArray(ast)) { | ||
| // eval | ||
| if (typeof ast == "string") { | ||
| return ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : E.throw(ast + " not found") // undefined symbol | ||
| } else { | ||
| return ast | ||
| } | ||
| } else { | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(env, ast[2]) | ||
| } else if (ast[0] == "~") { // mark as macro | ||
| return Object.assign(EVAL(env, ast[1]), {M: 1}) // mark as macro | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| return ast[1] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return 2 in el ? el[0][el[1]] = el[2] : x | ||
| } else if (ast[0] == ".") { // call object method | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".") { // call object method | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return x.apply(el[0], el.slice(2)) | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| let f = function(...a) { | ||
| return EVAL(ast[2], eval_ast_or_bind(ast[1], env, a)) | ||
| } | ||
| f.A = [ast[2], env, ast[1]] | ||
| return f | ||
| } | ||
| // TCO cases | ||
| if (ast[0] == "let") { // new environment with bindings | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| return Object.assign(function(...a) { | ||
| return EVAL(new_env(env, ast[1], a), ast.at(-1)) | ||
| }, [ast[2], env, ast[1]]) | ||
| // TCO cases | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| env = Object.create(env) | ||
| for (let i in ast[1]) { | ||
| if (i%2) { | ||
| env[ast[1][i-1]] = EVAL(ast[1][i], env) | ||
| } | ||
| } | ||
| ast = ast[2] | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| let el = eval_ast_or_bind(ast.slice(1,ast.length-1), env) | ||
| ast = ast[ast.length-1] | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(ast[1], env) ? ast[2] : ast[3] | ||
| } else { // invoke list form | ||
| let el = eval_ast_or_bind(ast, env), | ||
| f = el[0] | ||
| if (f.A) { | ||
| ast = f.A[0] | ||
| env = eval_ast_or_bind(f.A[2], f.A[1], el.slice(1)) | ||
| ast[1].map((e,i) => i%2 ? env[ast[1][i-1]] = EVAL(env, ast[1][i]) : 0) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| ast.slice(1,-1).map(v => EVAL(env, v)) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(env, ast[1]) ? ast[2] : ast.at(-1) | ||
| } else { // invoke list form | ||
| f = EVAL(env, ast[0]) | ||
| if (f.M) { | ||
| ast = f(...ast.slice(1)) | ||
| } else { | ||
| return f(...el.slice(1)) | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| if (0 in f) { | ||
| ast = f[0] | ||
| env = new_env(f[1], f[2], el) | ||
| } else { | ||
| return f(...el) | ||
| } | ||
| } | ||
| } | ||
| } | ||
@@ -96,26 +76,30 @@ } | ||
| let E = Object.assign(this, { | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(a[0], E), | ||
| E = Object.assign(this, { | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(E, a[0]), | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "isa": (...a) => a[0] instanceof a[1], | ||
| // new can use Reflect.construct | ||
| //"new": (...a) => new (a[0].bind(...a)), | ||
| // delete can use Reflect.deleteProperty | ||
| //"del": (...a) => delete a[0][a[1]], | ||
| //"list": (...a) => a, | ||
| //"map": (...a) => a[1].map(x => a[0](x)), | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "list": (...a) => a, | ||
| ///"map": (...a) => a[1].map(x => a[0](x)), | ||
| "throw": (...a) => { throw(a[0]) }, | ||
| /// isa can use isPrototypeOf | ||
| ///"isa": (...a) => a[0] instanceof a[1], | ||
| /// classOf is similar but more specific | ||
| ///"type": (...a) => typeof a[0], | ||
| /// new can use Reflect.construct | ||
| ///"new": (...a) => new (a[0].bind(...a)), | ||
| /// delete can use Reflect.deleteProperty | ||
| ///"del": (...a) => delete a[0][a[1]], | ||
| ///"load": (...a) => EVAL(E, JSON.parse(require("fs").readFileSync(a[0],"utf8"))), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "load": (...a) => EVAL(JSON.parse(require("fs").readFileSync(a[0],"utf8")),E), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "ARGS": process.argv.slice(3) | ||
| "argv": process.argv.slice(3) | ||
| }) | ||
@@ -125,10 +109,9 @@ | ||
| if (process.argv[2]) { | ||
| E.load(process.argv[2]) | ||
| return EVAL(E,JSON.parse(require("fs").readFileSync(process.argv[2]))) | ||
| } else { | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,EVAL(JSON.parse(a[0]),E)), | ||
| writer: JSON.stringify, | ||
| terminal: 0}) | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,JSON.stringify(EVAL(E, JSON.parse(a[0])))), | ||
| writer: (...a) => a[0]}) | ||
| } | ||
| }() |
@@ -1,1 +0,1 @@ | ||
| for(_=',nk]=xinz))|e($.slic$##1|I,tH[1]LiLKH)Q$KQPre__turn ^;^n7nL,6)=>5;i=4"==E[2]DiDC[0]B),ZnBYHZe=YXr(W{foW;VJSON.Ue.ATif(let {n=EiB)Wi#1){^$Ceval z [ntypeof throw_qui_("=Object.(...n:5"Yi.length-16"zstanceof "}else Array!(i|^WiQ;c_at$Upars$process.argvfunction)XL];^fs")._adFileSync(Y,"utf8")!(){ n(n,e)Vn&&Yz e&&eB].M;)n=eB]I7} $iQV;){i=n(iHZdef^t[Kx$CQ;~P7.M=1k}`^K;.-2n?YLxnD:e}.e.apply(Yk#2|}trytry{^P}catch(nD,W[CL]H,]| fn,WKHk|}7.A=[CH,K]k}let{tt);foWnK)n%2&&(t[K-1]x$K]Q)4C do,Zt)4i[] ifi=P?C:i[3];elseWiX;!T)^eI4TBH=WTD,TLkI}}}r=(n,rQ{^t?(rrZn.som$(e,i5"&Ee?r[i+1]xt#i):(r[ext[i],0)Zr):n?n.map(5$Y,r|:"En?nr?r]:i.(n+" not found"):n},iassign(this,{js:,$Y,iZ"====<<++--**//6isaY6{ Y},_adYZslurp,load$ZiZARGS:#3)});D?i.load(D):_pl").start({n[3](0,$YZi)Zwriter:UstrzgifyHermzal:0})}()';G=/[-T-ZB-E4-7^_PQKLHI#$|zxk]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='"==YreX[0]WYiW)VXturn UVUTi=R[rQ[1]PeP,I,r)H(t,G))E),D1).map(e=>aGe)DC.slice(Br=iBC7JSON.6Array5if(4rWQP]a(A,eval in ?t[itypeof Object.throwelse{4((eH=>(...eW:e)=>"XquiX("e){Ua(sGI"[2]functioni.at(-1)6parse( ;4"aGiprocess.argvt=cXate(tDiassign(fs").XadFileSync(;else 4T7F=, sGi,s){U.some"&YeQ+1]]=sBr):(t[e]=sQ],0)Dt} ,eH{for(;;){4!5.is5(iEU"Yi?it]:A.(i+" not found"):idefTt[iP]=)~TPD{M:1})`TiP.-2r?=r:F.F.apply(rW,rB2EtryVtry{UP)}catch([P],[e]D)}"fnTiP,eD)},[i,t,iP])letVP.mapr%2PQ-1]]=PQ]):0DR"doViB1,-CR"ifVRP)?i:(e=WE.M)ReiB1E;7!(0eEUer);R,t=s(IeH}}}}A=this,{js:,D"====<<++--**//Iliste,{ },Xad Dslurp,"utf8"Dargv:B3)}D? E):Xpl").start({e[3](0,6stringify( E)Dwriter})';G=/[^ -38-AFJ-OS[-~]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
@@ -1,1 +0,1 @@ | ||
| !function(){function n(n,e){for(;n instanceof Array&&n[0]in e&&e[n[0]].M;)n=e[n[0]](...n.slice(1));return n}function e(i,t){for(;;){if(!(i instanceof Array))return r(i,t);if(i=n(i,t),!(i instanceof Array))return r(i,t);if("def"==i[0])return t[i[1]]=e(i[2],t);if("~"==i[0]){let n=e(i[1],t);return n.M=1,n}if("`"==i[0])return i[1];if(".-"==i[0]){let n=r(i.slice(1),t),e=n[0][n[1]];return 2 in n?n[0][n[1]]=n[2]:e}if("."==i[0]){let n=r(i.slice(1),t),e=n[0][n[1]];return e.apply(n[0],n.slice(2))}if("try"==i[0])try{return e(i[1],t)}catch(n){return e(i[2][2],r([i[2][1]],t,[n]))}else if("fn"==i[0]){let n=function(...n){return e(i[2],r(i[1],t,n))};return n.A=[i[2],t,i[1]],n}if("let"==i[0]){t=Object.create(t);for(let n in i[1])n%2&&(t[i[1][n-1]]=e(i[1][n],t));i=i[2]}else if("do"==i[0]){let n=r(i.slice(1,i.length-1),t);i=i[i.length-1]}else if("if"==i[0])i=e(i[1],t)?i[2]:i[3];else{let n=r(i,t),e=n[0];if(!e.A)return e(...n.slice(1));i=e.A[0],t=r(e.A[2],e.A[1],n.slice(1))}}}let r=function(n,r,t){return t?(r=Object.create(r),n.some((e,i)=>"&"==e?r[n[i+1]]=t.slice(i):(r[e]=t[i],0)),r):n instanceof Array?n.map((...n)=>e(n[0],r)):typeof ""==typeof n?n in r?r[n]:i.throw(n+" not found"):n},i=Object.assign(this,{js:eval,eval:(...n)=>e(n[0],i),"=":(...n)=>n[0]===n[1],"<":(...n)=>n[0]<n[1],"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1],isa:(...n)=>n[0]instanceof n[1],throw:(...n)=>{throw n[0]},read:(...n)=>JSON.parse(n[0]),slurp:(...n)=>require("fs").readFileSync(n[0],"utf8"),load:(...n)=>e(JSON.parse(require("fs").readFileSync(n[0],"utf8")),i),ARGS:process.argv.slice(3)});process.argv[2]?i.load(process.argv[2]):require("repl").start({eval:(...n)=>n[3](0,e(JSON.parse(n[0]),i)),writer:JSON.stringify,terminal:0})}() | ||
| function s(t,i,s){return t=Object.create(t),i.some((e,r)=>"&"==e?t[i[r+1]]=s.slice(r):(t[e]=s[r],0)),t}function a(t,i,e,r){for(;;){if(!Array.isArray(i))return typeof ""==typeof i?i in t?t[i]:E.throw(i+" not found"):i;if("def"==i[0])return t[i[1]]=a(t,i[2]);if("~"==i[0])return Object.assign(a(t,i[1]),{M:1});if("`"==i[0])return i[1];if(".-"==i[0])return r=i.slice(1).map(e=>a(t,e)),x=r[0][r[1]],2 in r?r[0][r[1]]=r[2]:x;if("."==i[0])return r=i.slice(1).map(e=>a(t,e)),x=r[0][r[1]],x.apply(r[0],r.slice(2));if("try"==i[0])try{return a(t,i[1])}catch(e){return a(s(t,[i.at(-1)[1]],[e]),i.at(-1)[2])}else{if("fn"==i[0])return Object.assign(function(...e){return a(s(t,i[1],e),i.at(-1))},[i[2],t,i[1]]);if("let"==i[0])t=Object.create(t),i[1].map((e,r)=>r%2?t[i[1][r-1]]=a(t,i[1][r]):0),i=i.at(-1);else if("do"==i[0])i.slice(1,-1).map(e=>a(t,e)),i=i.at(-1);else if("if"==i[0])i=a(t,i[1])?i[2]:i.at(-1);else if((e=a(t,i[0])).M)i=e(...i.slice(1));else{if(r=i.slice(1).map(e=>a(t,e)),!(0 in e))return e(...r);i=e[0],t=s(e[1],e[2],r)}}}}E=Object.assign(this,{js:eval,eval:(...e)=>a(E,e[0]),"=":(...e)=>e[0]===e[1],"<":(...e)=>e[0]<e[1],"+":(...e)=>e[0]+e[1],"-":(...e)=>e[0]-e[1],"*":(...e)=>e[0]*e[1],"/":(...e)=>e[0]/e[1],list:(...e)=>e,throw:(...e)=>{throw e[0]},read:(...e)=>JSON.parse(e[0]),slurp:(...e)=>require("fs").readFileSync(e[0],"utf8"),argv:process.argv.slice(3)}),process.argv[2]?a(E,JSON.parse(require("fs").readFileSync(process.argv[2]))):require("repl").start({eval:(...e)=>e[3](0,JSON.stringify(a(E,JSON.parse(e[0])))),writer:(...e)=>e[0]}) |
+90
-109
@@ -1,99 +0,78 @@ | ||
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| /// miniMAL | ||
| /// Copyright (C) 2024 Joel Martin | ||
| /// Licensed under MPL 2.0 | ||
| !function() { | ||
| // 2 args: eval_ast, 3 args: env_bind | ||
| let eval_ast_or_bind = function(ast, env, exprs) { | ||
| if (exprs) { | ||
| // Return new Env with symbols in ast bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| ast.some((a,i) => a == "&" ? env[ast[i+1]] = exprs.slice(i) | ||
| : (env[a] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| // Evaluate the form/ast | ||
| return ast instanceof Array // list? | ||
| ? ast.map((...a) => EVAL(a[0], env)) // list | ||
| : (typeof ast == "string") // symbol? | ||
| ? ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : E.throw(ast + " not found") // undefined symbol | ||
| ///: null[ast] // undefined symbol | ||
| : ast // ast unchanged | ||
| function new_env(env, binds, exprs) { | ||
| // Return new Env with symbols in binds bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| binds.some((b,i) => b == "&" ? env[binds[i+1]] = exprs.slice(i) | ||
| : (env[b] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| function macroexpand(ast, env) { | ||
| while (ast instanceof Array | ||
| && ast[0] in env | ||
| && env[ast[0]].M) { | ||
| ast = env[ast[0]](...ast.slice(1)) | ||
| } | ||
| return ast | ||
| } | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast, f, el) { | ||
| while (true) { | ||
| //console.log("EVAL:", ast) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| // apply | ||
| ast = macroexpand(ast, env) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(ast[2], env) | ||
| } else if (ast[0] == "~") { // mark as macro | ||
| let f = EVAL(ast[1], env) // eval regular function | ||
| f.M = 1 // mark as macro | ||
| return f | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| if (!Array.isArray(ast)) { | ||
| // eval | ||
| if (typeof ast == "string") { | ||
| return ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : E.throw(ast + " not found") // undefined symbol | ||
| } else { | ||
| return ast | ||
| } | ||
| } else { | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(env, ast[2]) | ||
| } else if (ast[0] == "~") { // mark as macro | ||
| return Object.assign(EVAL(env, ast[1]), {M: 1}) // mark as macro | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| return ast[1] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return 2 in el ? el[0][el[1]] = el[2] : x | ||
| } else if (ast[0] == ".") { // call object method | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".") { // call object method | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return x.apply(el[0], el.slice(2)) | ||
| } else if (ast[0] == "try") { // try/catch | ||
| } else if (ast[0] == "try") { // try/catch | ||
| try { | ||
| return EVAL(ast[1], env) | ||
| return EVAL(env, ast[1]) | ||
| } catch (e) { | ||
| return EVAL(ast[2][2], eval_ast_or_bind([ast[2][1]], env, [e])) | ||
| return EVAL(new_env(env, [ast.at(-1)[1]], [e]), ast.at(-1)[2]) | ||
| } | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| let f = function(...a) { | ||
| return EVAL(ast[2], eval_ast_or_bind(ast[1], env, a)) | ||
| } | ||
| f.A = [ast[2], env, ast[1]] | ||
| return f | ||
| } | ||
| // TCO cases | ||
| if (ast[0] == "let") { // new environment with bindings | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| return Object.assign(function(...a) { | ||
| return EVAL(new_env(env, ast[1], a), ast.at(-1)) | ||
| }, [ast[2], env, ast[1]]) | ||
| // TCO cases | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| env = Object.create(env) | ||
| for (let i in ast[1]) { | ||
| if (i%2) { | ||
| env[ast[1][i-1]] = EVAL(ast[1][i], env) | ||
| } | ||
| } | ||
| ast = ast[2] | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| let el = eval_ast_or_bind(ast.slice(1,ast.length-1), env) | ||
| ast = ast[ast.length-1] | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(ast[1], env) ? ast[2] : ast[3] | ||
| } else { // invoke list form | ||
| let el = eval_ast_or_bind(ast, env), | ||
| f = el[0] | ||
| if (f.A) { | ||
| ast = f.A[0] | ||
| env = eval_ast_or_bind(f.A[2], f.A[1], el.slice(1)) | ||
| ast[1].map((e,i) => i%2 ? env[ast[1][i-1]] = EVAL(env, ast[1][i]) : 0) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| ast.slice(1,-1).map(v => EVAL(env, v)) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(env, ast[1]) ? ast[2] : ast.at(-1) | ||
| } else { // invoke list form | ||
| f = EVAL(env, ast[0]) | ||
| if (f.M) { | ||
| ast = f(...ast.slice(1)) | ||
| } else { | ||
| return f(...el.slice(1)) | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| if (0 in f) { | ||
| ast = f[0] | ||
| env = new_env(f[1], f[2], el) | ||
| } else { | ||
| return f(...el) | ||
| } | ||
| } | ||
| } | ||
| } | ||
@@ -103,27 +82,30 @@ } | ||
| let E = Object.assign(this, { | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(a[0], E), | ||
| E = Object.assign(this, { | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(E, a[0]), | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "isa": (...a) => a[0] instanceof a[1], | ||
| // new can use Reflect.construct | ||
| //"new": (...a) => new (a[0].bind(...a)), | ||
| // delete can use Reflect.deleteProperty | ||
| //"del": (...a) => delete a[0][a[1]], | ||
| //"list": (...a) => a, | ||
| //"map": (...a) => a[1].map(x => a[0](x)), | ||
| "throw": (...a) => { throw(a[0]) }, | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "list": (...a) => a, | ||
| ///"map": (...a) => a[1].map(x => a[0](x)), | ||
| "throw": (...a) => { throw(a[0]) }, | ||
| /// isa can use isPrototypeOf | ||
| ///"isa": (...a) => a[0] instanceof a[1], | ||
| /// classOf is similar but more specific | ||
| ///"type": (...a) => typeof a[0], | ||
| /// new can use Reflect.construct | ||
| ///"new": (...a) => new (a[0].bind(...a)), | ||
| /// delete can use Reflect.deleteProperty | ||
| ///"del": (...a) => delete a[0][a[1]], | ||
| ///"load": (...a) => EVAL(E, JSON.parse(require("fs").readFileSync(a[0],"utf8"))), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "load": (...a) => EVAL(JSON.parse(require("fs").readFileSync(a[0],"utf8")),E), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "ARGS": process.argv.slice(3) | ||
| "argv": process.argv.slice(3) | ||
| }) | ||
@@ -133,10 +115,9 @@ | ||
| if (process.argv[2]) { | ||
| E.load(process.argv[2]) | ||
| return EVAL(E,JSON.parse(require("fs").readFileSync(process.argv[2]))) | ||
| } else { | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,EVAL(JSON.parse(a[0]),E)), | ||
| writer: JSON.stringify, | ||
| terminal: 0}) | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,JSON.stringify(EVAL(E, JSON.parse(a[0])))), | ||
| writer: (...a) => a[0]}) | ||
| } | ||
| }() |
@@ -1,1 +0,1 @@ | ||
| for(_=',nk]=xinz))|e($.slic$##1|I,tH[1]LiLKH)Q$KQPre__turn ^;^n7nL,6)=>5;i=4"==E[2]DiDC[0]B),ZnBYHZe=YXr(W{foW;VJSON.Ue.ATif(let {n=EiB)Wi#1){^$Ceval z [ntypeof throw_qui_("=Object.(...n:5"Yi.length-16"zstanceof "}else Array!(i|^WiQ;c_at$Upars$process.argvfunction)XL];^fs")._adFileSync(Y,"utf8")!(){ n(n,e)Vn&&Yz e&&eB].M;)n=eB]I7} $iQV;){i=n(iHZdef^t[Kx$CQ;~P7.M=1k}`^K;.-2n?YLxnD:e}.e.apply(Yk#2|}trytry{^P}catch(nD,W[CL]H,]| fn,WKHk|}7.A=[CH,K]k}let{tt);foWnK)n%2&&(t[K-1]x$K]Q)4C do,Zt)4i[] ifi=P?C:i[3];elseWiX;!T)^eI4TBH=WTD,TLkI}}}r=(n,rQ{^t?(rrZn.som$(e,i5"&Ee?r[i+1]xt#i):(r[ext[i],0)Zr):n?n.map(5$Y,r|:"En?nr?r]:i.(n+" not found"):n},iassign(this,{js:,$Y,iZ"====<<++--**//6isaY6{ Y},_adYZslurp,load$ZiZARGS:#3)});D?i.load(D):_pl").start({n[3](0,$YZi)Zwriter:UstrzgifyHermzal:0})}()';G=/[-T-ZB-E4-7^_PQKLHI#$|zxk]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='reY[0]X"==iX)WYturn VWVUi=T):R(t,QaQiP]=PL[1]KeK,I,r)H))G),E1).map(e=>aQe)ED.slice(Cr=iCDB[r7rX7K]6JSON.5Array4if(typeof ==i?ia(A,eval in ?t[ithrowelse{(...eX:e)=>"YquiY("e){Va(sQI"Object.[2]assign(((eH=>function t=cYate(tEii.at(-1)5parse(;"process.argvfs").YadFileSync(;else UBF=6, sQi,s){V.some"&"==e7+1]]=sCrR(t[e]=s7],0)Et} P,eH{for(;;){!4.is4(iGV""t]:A.(i+" not found"R{}&&keys(i).Yduce(e7L7]EeE{}RidefUt[iKL)~UPKE{M:1})`UiK.-2r?6=r:F.F.apply(rX,rC2GtryWtry{VPK)}catch([K],[e]E)}"fnU iK,eE)},[i,t,iK])letWK.mapr%2K7-1]LK7]R0ET"doWiC1,-DT"ifWTPK)?i:(e=PXG.M)TeiC1G;B!(0eGVer);T,t=s(IeH}}}}A=this,{js:,E"====<<++--**//Iliste,{ },YadEslurp,"utf8"Eargv:C3)}E?GRYpl").start({e[3](0,5stringify(G)Ewriter})';G=/[^ -38-AFJM-OS[-~]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
@@ -1,1 +0,1 @@ | ||
| !function(){function n(n,e){for(;n instanceof Array&&n[0]in e&&e[n[0]].M;)n=e[n[0]](...n.slice(1));return n}function e(i,t){for(;;){if(!(i instanceof Array))return r(i,t);if(i=n(i,t),!(i instanceof Array))return r(i,t);if("def"==i[0])return t[i[1]]=e(i[2],t);if("~"==i[0]){let n=e(i[1],t);return n.M=1,n}if("`"==i[0])return i[1];if(".-"==i[0]){let n=r(i.slice(1),t),e=n[0][n[1]];return 2 in n?n[0][n[1]]=n[2]:e}if("."==i[0]){let n=r(i.slice(1),t),e=n[0][n[1]];return e.apply(n[0],n.slice(2))}if("try"==i[0])try{return e(i[1],t)}catch(n){return e(i[2][2],r([i[2][1]],t,[n]))}else if("fn"==i[0]){let n=function(...n){return e(i[2],r(i[1],t,n))};return n.A=[i[2],t,i[1]],n}if("let"==i[0]){t=Object.create(t);for(let n in i[1])n%2&&(t[i[1][n-1]]=e(i[1][n],t));i=i[2]}else if("do"==i[0]){let n=r(i.slice(1,i.length-1),t);i=i[i.length-1]}else if("if"==i[0])i=e(i[1],t)?i[2]:i[3];else{let n=r(i,t),e=n[0];if(!e.A)return e(...n.slice(1));i=e.A[0],t=r(e.A[2],e.A[1],n.slice(1))}}}let r=function(n,r,t){return t?(r=Object.create(r),n.some((e,i)=>"&"==e?r[n[i+1]]=t.slice(i):(r[e]=t[i],0)),r):n instanceof Array?n.map((...n)=>e(n[0],r)):typeof ""==typeof n?n in r?r[n]:i.throw(n+" not found"):n},i=Object.assign(this,{js:eval,eval:(...n)=>e(n[0],i),"=":(...n)=>n[0]===n[1],"<":(...n)=>n[0]<n[1],"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1],isa:(...n)=>n[0]instanceof n[1],throw:(...n)=>{throw n[0]},read:(...n)=>JSON.parse(n[0]),slurp:(...n)=>require("fs").readFileSync(n[0],"utf8"),load:(...n)=>e(JSON.parse(require("fs").readFileSync(n[0],"utf8")),i),ARGS:process.argv.slice(3)});process.argv[2]?i.load(process.argv[2]):require("repl").start({eval:(...n)=>n[3](0,e(JSON.parse(n[0]),i)),writer:JSON.stringify,terminal:0})}() | ||
| function s(t,i,s){return t=Object.create(t),i.some((e,r)=>"&"==e?t[i[r+1]]=s.slice(r):(t[e]=s[r],0)),t}function a(t,i,e,r){for(;;){if(!Array.isArray(i))return typeof ""==typeof i?i in t?t[i]:E.throw(i+" not found"):typeof {}==typeof i?i&&Object.keys(i).reduce((e,r)=>(e[r]=a(t,i[r]),e),{}):i;if("def"==i[0])return t[i[1]]=a(t,i[2]);if("~"==i[0])return Object.assign(a(t,i[1]),{M:1});if("`"==i[0])return i[1];if(".-"==i[0])return r=i.slice(1).map(e=>a(t,e)),x=r[0][r[1]],2 in r?r[0][r[1]]=r[2]:x;if("."==i[0])return r=i.slice(1).map(e=>a(t,e)),x=r[0][r[1]],x.apply(r[0],r.slice(2));if("try"==i[0])try{return a(t,i[1])}catch(e){return a(s(t,[i.at(-1)[1]],[e]),i.at(-1)[2])}else{if("fn"==i[0])return Object.assign(function(...e){return a(s(t,i[1],e),i.at(-1))},[i[2],t,i[1]]);if("let"==i[0])t=Object.create(t),i[1].map((e,r)=>r%2?t[i[1][r-1]]=a(t,i[1][r]):0),i=i.at(-1);else if("do"==i[0])i.slice(1,-1).map(e=>a(t,e)),i=i.at(-1);else if("if"==i[0])i=a(t,i[1])?i[2]:i.at(-1);else if((e=a(t,i[0])).M)i=e(...i.slice(1));else{if(r=i.slice(1).map(e=>a(t,e)),!(0 in e))return e(...r);i=e[0],t=s(e[1],e[2],r)}}}}E=Object.assign(this,{js:eval,eval:(...e)=>a(E,e[0]),"=":(...e)=>e[0]===e[1],"<":(...e)=>e[0]<e[1],"+":(...e)=>e[0]+e[1],"-":(...e)=>e[0]-e[1],"*":(...e)=>e[0]*e[1],"/":(...e)=>e[0]/e[1],list:(...e)=>e,throw:(...e)=>{throw e[0]},read:(...e)=>JSON.parse(e[0]),slurp:(...e)=>require("fs").readFileSync(e[0],"utf8"),argv:process.argv.slice(3)}),process.argv[2]?a(E,JSON.parse(require("fs").readFileSync(process.argv[2]))):require("repl").start({eval:(...e)=>e[3](0,JSON.stringify(a(E,JSON.parse(e[0])))),writer:(...e)=>e[0]}) |
+95
-109
@@ -1,99 +0,83 @@ | ||
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| /// miniMAL | ||
| /// Copyright (C) 2024 Joel Martin | ||
| /// Licensed under MPL 2.0 | ||
| !function() { | ||
| // 2 args: eval_ast, 3 args: env_bind | ||
| let eval_ast_or_bind = function(ast, env, exprs) { | ||
| if (exprs) { | ||
| // Return new Env with symbols in ast bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| ast.some((a,i) => a == "&" ? env[ast[i+1]] = exprs.slice(i) | ||
| : (env[a] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| // Evaluate the form/ast | ||
| return ast instanceof Array // list? | ||
| ? ast.map((...a) => EVAL(a[0], env)) // list | ||
| : (typeof ast == "string") // symbol? | ||
| ? ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : E.throw(ast + " not found") // undefined symbol | ||
| ///: null[ast] // undefined symbol | ||
| : ast // ast unchanged | ||
| function new_env(env, binds, exprs) { | ||
| // Return new Env with symbols in binds bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| binds.some((b,i) => b == "&" ? env[binds[i+1]] = exprs.slice(i) | ||
| : (env[b] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| function macroexpand(ast, env) { | ||
| while (ast instanceof Array | ||
| && ast[0] in env | ||
| && env[ast[0]].M) { | ||
| ast = env[ast[0]](...ast.slice(1)) | ||
| } | ||
| return ast | ||
| } | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast, f, el) { | ||
| while (true) { | ||
| //console.log("EVAL:", ast) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| // apply | ||
| ast = macroexpand(ast, env) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(ast[2], env) | ||
| } else if (ast[0] == "~") { // mark as macro | ||
| let f = EVAL(ast[1], env) // eval regular function | ||
| f.M = 1 // mark as macro | ||
| return f | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| if (!Array.isArray(ast)) { | ||
| // eval | ||
| if (typeof ast == "string") { | ||
| return ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : E.throw(ast + " not found") // undefined symbol | ||
| } else { | ||
| return (typeof ast == "object") | ||
| ? ast | ||
| ? Object.keys(ast).reduce( | ||
| (a,k) => (a[k] = EVAL(env, ast[k]), a), {}) // eval object values | ||
| : ast // return ast unchanged | ||
| : ast | ||
| } | ||
| } else { | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(env, ast[2]) | ||
| } else if (ast[0] == "~") { // mark as macro | ||
| return Object.assign(EVAL(env, ast[1]), {M: 1}) // mark as macro | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| return ast[1] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return 2 in el ? el[0][el[1]] = el[2] : x | ||
| } else if (ast[0] == ".") { // call object method | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".") { // call object method | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return x.apply(el[0], el.slice(2)) | ||
| } else if (ast[0] == "try") { // try/catch | ||
| } else if (ast[0] == "try") { // try/catch | ||
| try { | ||
| return EVAL(ast[1], env) | ||
| return EVAL(env, ast[1]) | ||
| } catch (e) { | ||
| return EVAL(ast[2][2], eval_ast_or_bind([ast[2][1]], env, [e])) | ||
| return EVAL(new_env(env, [ast.at(-1)[1]], [e]), ast.at(-1)[2]) | ||
| } | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| let f = function(...a) { | ||
| return EVAL(ast[2], eval_ast_or_bind(ast[1], env, a)) | ||
| } | ||
| f.A = [ast[2], env, ast[1]] | ||
| return f | ||
| } | ||
| // TCO cases | ||
| if (ast[0] == "let") { // new environment with bindings | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| return Object.assign(function(...a) { | ||
| return EVAL(new_env(env, ast[1], a), ast.at(-1)) | ||
| }, [ast[2], env, ast[1]]) | ||
| // TCO cases | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| env = Object.create(env) | ||
| for (let i in ast[1]) { | ||
| if (i%2) { | ||
| env[ast[1][i-1]] = EVAL(ast[1][i], env) | ||
| } | ||
| } | ||
| ast = ast[2] | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| let el = eval_ast_or_bind(ast.slice(1,ast.length-1), env) | ||
| ast = ast[ast.length-1] | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(ast[1], env) ? ast[2] : ast[3] | ||
| } else { // invoke list form | ||
| let el = eval_ast_or_bind(ast, env), | ||
| f = el[0] | ||
| if (f.A) { | ||
| ast = f.A[0] | ||
| env = eval_ast_or_bind(f.A[2], f.A[1], el.slice(1)) | ||
| ast[1].map((e,i) => i%2 ? env[ast[1][i-1]] = EVAL(env, ast[1][i]) : 0) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| ast.slice(1,-1).map(v => EVAL(env, v)) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(env, ast[1]) ? ast[2] : ast.at(-1) | ||
| } else { // invoke list form | ||
| f = EVAL(env, ast[0]) | ||
| if (f.M) { | ||
| ast = f(...ast.slice(1)) | ||
| } else { | ||
| return f(...el.slice(1)) | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| if (0 in f) { | ||
| ast = f[0] | ||
| env = new_env(f[1], f[2], el) | ||
| } else { | ||
| return f(...el) | ||
| } | ||
| } | ||
| } | ||
| } | ||
@@ -103,27 +87,30 @@ } | ||
| let E = Object.assign(this, { | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(a[0], E), | ||
| E = Object.assign(this, { | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(E, a[0]), | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "isa": (...a) => a[0] instanceof a[1], | ||
| // new can use Reflect.construct | ||
| //"new": (...a) => new (a[0].bind(...a)), | ||
| // delete can use Reflect.deleteProperty | ||
| //"del": (...a) => delete a[0][a[1]], | ||
| //"list": (...a) => a, | ||
| //"map": (...a) => a[1].map(x => a[0](x)), | ||
| "throw": (...a) => { throw(a[0]) }, | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "list": (...a) => a, | ||
| ///"map": (...a) => a[1].map(x => a[0](x)), | ||
| "throw": (...a) => { throw(a[0]) }, | ||
| /// isa can use isPrototypeOf | ||
| ///"isa": (...a) => a[0] instanceof a[1], | ||
| /// classOf is similar but more specific | ||
| ///"type": (...a) => typeof a[0], | ||
| /// new can use Reflect.construct | ||
| ///"new": (...a) => new (a[0].bind(...a)), | ||
| /// delete can use Reflect.deleteProperty | ||
| ///"del": (...a) => delete a[0][a[1]], | ||
| ///"load": (...a) => EVAL(E, JSON.parse(require("fs").readFileSync(a[0],"utf8"))), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "load": (...a) => EVAL(JSON.parse(require("fs").readFileSync(a[0],"utf8")),E), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "ARGS": process.argv.slice(3) | ||
| "argv": process.argv.slice(3) | ||
| }) | ||
@@ -133,10 +120,9 @@ | ||
| if (process.argv[2]) { | ||
| E.load(process.argv[2]) | ||
| return EVAL(E,JSON.parse(require("fs").readFileSync(process.argv[2]))) | ||
| } else { | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,EVAL(JSON.parse(a[0]),E)), | ||
| writer: JSON.stringify, | ||
| terminal: 0}) | ||
| require("repl").start({ | ||
| eval: (...a) => a[3](0,JSON.stringify(EVAL(E, JSON.parse(a[0])))), | ||
| writer: (...a) => a[0]}) | ||
| } | ||
| }() |
@@ -1,1 +0,1 @@ | ||
| for(_='",qe(wrez["|q|~q"$~`$#;t=_[e]^[2]6=n5if4)=>R(...Q:QnRnPinG.GnerF[1]Ee G tDJSON.Z("\\n"YmapX,i)W[0]VW,f5VUfac~pz>4("}else typeof ]]]\\n|let(t.X(e=>=Object.],|))FTextt.length-1nE,"t6,tV.onkeyup1]]functionQeRn(eV,f.ast czatw{ n=e Gstanceof Array.slicwzturn "==tV)"PV1)U[n[; nW{for(;;){4(!eW;defi[t[5(W;`tE;.-2 G n?nV[n[56:f}.f.apply(nV,n2}fn{ f=Qf){n(,eE,i,f}; =[,i,t[,f}{ii);for( DE)e%2&&(i[tE[e-5E^,i_do1,)W_t[]4t5EW?:t[3];elseU;4(! )fQn1_ V,i=w 6, E,n1}}}var e=(e,tW{i?t),e.somw(n,fR"&"=5?t[e[f+=if):[n]=i[f],0,t):e?e.X(t:""==e?D?t^:null^:e};Aassignhis,{js:eval,eval:A),"====<<++--**//nE,XPEnV(e}),bFHTML=\\\'<pz contenteditable>|~m#mGi"]+$m#MAL"def$fn~n"4$n~*$n~-$nq],]\\n|X$`q[7,8,9.-q |.-$document#body"]`$bgColor"`$cyan"]]</<</\\\'=b.childzn=((RtE=tV.splitY)e?ZstrGg4y(n(Zparswe),A:"").joGY()';G=/[-U-ZD-GP-R4-6^_#$~|zwq]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='in@,eI[tK,[q","z"q"||`z$val#"==_,t^(e5))4map3(n,R),Q.35=>P1)PaRe)QG.slice(Ft=rFGEJSON.DArrayCif(B)=>Z]]Y[0]X[1]WtXKW]V.#ueUfac| @ ?n[rtypeof Object.("\\n")throwelse{B(5^Z[2]return e){a(iReW,"(...^X.onkeyuptextareafunctionY]\\n[":eZr.at(-1);B" aRrn=create(nQrassign(< rows=9 cols=60>;else B_rX)"eXEx=V, iRr,i){.some"&_eK+1Y=iFt):(n[e]=iK],0)Qn} I^){for(;;){B!C.isC(r4"_r?rn]:A.(r+" not found"):r defn[rW]=) ~WQ{M:1}) `rW .-2t?V=t:x .x.apply(tX^F24 trytry{W)}catch([W]qe]Q)}"fnrWIQ)}qr,n,rW]) letW.3t%2WK-1Y=WK]):0Qr="dorF1,-Gr="ifr=W)?r:5=X4.M)r=erF14;E!(0e4et);r=eX,n=i5WI^)}}}}A=this,{js:e#I#a(AIXQ"====<<++--**//eW,3:tZtWPtX5)Q{ eX}}Qb.@nerHTML=\'["let|m$m@i"Yq"+zm$MAL"defzfn|n"]q"ifzn|*zn|-zn",1Y],13z`"q7,8,9.zMath$random"Y</></>\'^=b.children=(ZtWU=tXU.splitPe?Dstr@gify(a(A,Dparse54):"").jo@()';G=/[-U-ZB-GP-R3-5^_#$|zqKI@]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
@@ -1,1 +0,1 @@ | ||
| function n(t,i){for(;;){if(!(t instanceof Array))return e(t,i);if("def"==t[0])return i[t[1]]=n(t[2],i);if("`"==t[0])return t[1];if(".-"==t[0]){let n=e(t.slice(1),i),f=n[0][n[1]];return 2 in n?n[0][n[1]]=n[2]:f}if("."==t[0]){let n=e(t.slice(1),i),f=n[0][n[1]];return f.apply(n[0],n.slice(2))}if("fn"==t[0]){let f=function(...f){return n(t[2],e(t[1],i,f))};return f.ast=[t[2],i,t[1]],f}if("let"==t[0]){i=Object.create(i);for(let e in t[1])e%2&&(i[t[1][e-1]]=n(t[1][e],i));t=t[2]}else if("do"==t[0]){let n=e(t.slice(1,t.length-1),i);t=t[t.length-1]}else if("if"==t[0])t=n(t[1],i)?t[2]:t[3];else{let n=e(t,i),f=n[0];if(!f.ast)return f(...n.slice(1));t=f.ast[0],i=e(f.ast[2],f.ast[1],n.slice(1))}}}var e=function(e,t,i){return i?(t=Object.create(t),e.some((n,f)=>"&"==n?t[e[f+1]]=i.slice(f):(t[n]=i[f],0)),t):e instanceof Array?e.map((...e)=>n(e[0],t)):typeof ""==typeof e?e in t?t[e]:null[e]:e};E=Object.assign(this,{js:eval,eval:(...e)=>n(e[0],E),"=":(...n)=>n[0]===n[1],"<":(...n)=>n[0]<n[1],"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1],map:(...n)=>n[1].map(e=>n[0](e))}),b.innerHTML='<pre contenteditable>["let",["m",["`","mini"]],["+","m",["`","MAL"]]]\n["def","fac",["fn",["n"],["if","n",["*","n",["fac",["-","n",1]]],1]]]\n["map","fac",["`",[7,8,9]]]\n[".-", [".-","document",["`","body"]],["`","bgColor"],["`","cyan"]]</pre><pre></pre>',t=b.children,t[0].onkeyup=(()=>t[1].innerText=t[0].innerText.split("\n").map(e=>e?JSON.stringify(n(JSON.parse(e),E)):"").join("\n")),t[0].onkeyup() | ||
| function i(n,r,i){return n=Object.create(n),r.some((e,t)=>"&"==e?n[r[t+1]]=i.slice(t):(n[e]=i[t],0)),n}function a(n,r,e,t){for(;;){if(!Array.isArray(r))return typeof ""==typeof r?r in n?n[r]:E.throw(r+" not found"):r;if("def"==r[0])return n[r[1]]=a(n,r[2]);if("~"==r[0])return Object.assign(a(n,r[1]),{M:1});if("`"==r[0])return r[1];if(".-"==r[0])return t=r.slice(1).map(e=>a(n,e)),x=t[0][t[1]],2 in t?t[0][t[1]]=t[2]:x;if("."==r[0])return t=r.slice(1).map(e=>a(n,e)),x=t[0][t[1]],x.apply(t[0],t.slice(2));if("try"==r[0])try{return a(n,r[1])}catch(e){return a(i(n,[r.at(-1)[1]],[e]),r.at(-1)[2])}else{if("fn"==r[0])return Object.assign(function(...e){return a(i(n,r[1],e),r.at(-1))},[r[2],n,r[1]]);if("let"==r[0])n=Object.create(n),r[1].map((e,t)=>t%2?n[r[1][t-1]]=a(n,r[1][t]):0),r=r.at(-1);else if("do"==r[0])r.slice(1,-1).map(e=>a(n,e)),r=r.at(-1);else if("if"==r[0])r=a(n,r[1])?r[2]:r.at(-1);else if((e=a(n,r[0])).M)r=e(...r.slice(1));else{if(t=r.slice(1).map(e=>a(n,e)),!(0 in e))return e(...t);r=e[0],n=i(e[1],e[2],t)}}}}E=Object.assign(this,{js:eval,eval:(...e)=>a(E,e[0]),"=":(...e)=>e[0]===e[1],"<":(...e)=>e[0]<e[1],"+":(...e)=>e[0]+e[1],"-":(...e)=>e[0]-e[1],"*":(...e)=>e[0]*e[1],"/":(...e)=>e[0]/e[1],map:(...t)=>t[1].map(e=>t[0](e)),throw:(...e)=>{throw e[0]}}),b.innerHTML='<textarea rows=9 cols=60>["let",["m",["`","mini"]],["+","m",["`","MAL"]]]\n["def","fac",["fn",["n"],["if","n",["*","n",["fac",["-","n",1]]],1]]]\n["map","fac",["`",[7,8,9]]]\n[".","Math",["`","random"]]</textarea><textarea rows=9 cols=60></textarea>',t=b.children,t[0].onkeyup=()=>t[1].value=t[0].value.split("\n").map(e=>e?JSON.stringify(a(E,JSON.parse(e))):"").join("\n"),t[0].onkeyup() |
+87
-82
@@ -1,74 +0,76 @@ | ||
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| /// miniMAL | ||
| /// Copyright (C) 2024 Joel Martin | ||
| /// Licensed under MPL 2.0 | ||
| // 2 args: eval_ast, 3 args: env_bind | ||
| var eval_ast_or_bind = function(ast, env, exprs) { | ||
| if (exprs) { | ||
| // Return new Env with symbols in ast bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| ast.some((a,i) => a == "&" ? env[ast[i+1]] = exprs.slice(i) | ||
| : (env[a] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| // Evaluate the form/ast | ||
| return ast instanceof Array // list? | ||
| ? ast.map((...a) => EVAL(a[0], env)) // list | ||
| : (typeof ast == "string") // symbol? | ||
| ? ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : null[ast] // undefined symbol | ||
| : ast // ast unchanged | ||
| function new_env(env, binds, exprs) { | ||
| // Return new Env with symbols in binds bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| binds.some((b,i) => b == "&" ? env[binds[i+1]] = exprs.slice(i) | ||
| : (env[b] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast, f, el) { | ||
| while (true) { | ||
| //console.log("EVAL:", ast) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(ast[2], env) | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| if (!Array.isArray(ast)) { | ||
| // eval | ||
| if (typeof ast == "string") { | ||
| return ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : E.throw(ast + " not found") // undefined symbol | ||
| } else { | ||
| return ast | ||
| } | ||
| } else { | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(env, ast[2]) | ||
| } else if (ast[0] == "~") { // mark as macro | ||
| return Object.assign(EVAL(env, ast[1]), {M: 1}) // mark as macro | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| return ast[1] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return 2 in el ? el[0][el[1]] = el[2] : x | ||
| } else if (ast[0] == ".") { // call object method | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".") { // call object method | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return x.apply(el[0], el.slice(2)) | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| let f = function(...a) { | ||
| return EVAL(ast[2], eval_ast_or_bind(ast[1], env, a)) | ||
| } else if (ast[0] == "try") { // try/catch | ||
| try { | ||
| return EVAL(env, ast[1]) | ||
| } catch (e) { | ||
| return EVAL(new_env(env, [ast.at(-1)[1]], [e]), ast.at(-1)[2]) | ||
| } | ||
| f.ast = [ast[2], env, ast[1]] // f.ast compresses more than f.data | ||
| return f | ||
| } | ||
| // TCO cases | ||
| if (ast[0] == "let") { // new environment with bindings | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| return Object.assign(function(...a) { | ||
| return EVAL(new_env(env, ast[1], a), ast.at(-1)) | ||
| }, [ast[2], env, ast[1]]) | ||
| // TCO cases | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| env = Object.create(env) | ||
| for (let i in ast[1]) { | ||
| if (i%2) { | ||
| env[ast[1][i-1]] = EVAL(ast[1][i], env) | ||
| } | ||
| } | ||
| ast = ast[2] | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| let el = eval_ast_or_bind(ast.slice(1,ast.length-1), env) | ||
| ast = ast[ast.length-1] | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(ast[1], env) ? ast[2] : ast[3] | ||
| } else { // invoke list form | ||
| let el = eval_ast_or_bind(ast, env), | ||
| f = el[0] | ||
| if (f.ast) { | ||
| ast = f.ast[0] | ||
| env = eval_ast_or_bind(f.ast[2], f.ast[1], el.slice(1)) // TCO | ||
| ast[1].map((e,i) => i%2 ? env[ast[1][i-1]] = EVAL(env, ast[1][i]) : 0) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| ast.slice(1,-1).map(v => EVAL(env, v)) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(env, ast[1]) ? ast[2] : ast.at(-1) | ||
| } else { // invoke list form | ||
| f = EVAL(env, ast[0]) | ||
| if (f.M) { | ||
| ast = f(...ast.slice(1)) | ||
| } else { | ||
| return f(...el.slice(1)) | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| if (0 in f) { | ||
| ast = f[0] | ||
| env = new_env(f[1], f[2], el) | ||
| } else { | ||
| return f(...el) | ||
| } | ||
| } | ||
| } | ||
| } | ||
@@ -79,23 +81,27 @@ } | ||
| E = Object.assign(this, { | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(a[0], E), | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(E, a[0]), | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| //"isa": (...a) => a[0] instanceof a[1], | ||
| //"type": (...a) => typeof a[0], | ||
| //"new": (...a) => new (a[0].bind.apply(a[0], a)), | ||
| //"del": (...a) => delete a[0][a[1]], | ||
| //"list": (...a) => a, | ||
| "map": (...a) => a[1].map(x => a[0](x)), | ||
| //"throw": (...a) => { throw(a[0]) }, | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| ///"list": (...a) => a, | ||
| "map": (...a) => a[1].map(x => a[0](x)), | ||
| "throw": (...a) => { throw(a[0]) }, | ||
| /// isa can use isPrototypeOf | ||
| ///"isa": (...a) => a[0] instanceof a[1], | ||
| /// classOf is similar but more specific | ||
| ///"type": (...a) => typeof a[0], | ||
| /// new can use Reflect.construct | ||
| ///"new": (...a) => new (a[0].bind(...a)), | ||
| /// delete can use Reflect.deleteProperty | ||
| ///"del": (...a) => delete a[0][a[1]], | ||
| ///"load": (...a) => EVAL(E, JSON.parse(require("fs").readFileSync(a[0],"utf8"))), | ||
| //"read": (...a) => JSON.parse(a[0]), | ||
| //"slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| //"load": (...a) => EVAL(JSON.parse(E["slurp"](a[0])),E), | ||
| ///"read": (...a) => JSON.parse(a[0]), | ||
| ///"slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| }) | ||
@@ -105,3 +111,2 @@ | ||
| b.innerHTML = '<textarea rows=9 cols=60>["let",["m",["`","mini"]],["+","m",["`","MAL"]]]\n["def","fac",["fn",["n"],["if","n",["*","n",["fac",["-","n",1]]],1]]]\n["map","fac",["`",[7,8,9]]]\n[".","Math",["`","random"]]</textarea><textarea rows=9 cols=60></textarea>' | ||
| //b.innerHTML = '<textarea rows=9 cols=60>["let",["m",["`","mini"]],["+","m",["`","MAL"]]]\n["def","fac",["fn",["n"],["if","n",["*","n",["fac",["-","n",1]]],1]]]\n["map","fac",["`",[7,8,9]]]\n[".-", [".-",[".-","t",1],["`","style"]],["`","color"],["`","red"]]</textarea><textarea rows=9 cols=60></textarea>' | ||
@@ -111,4 +116,4 @@ t = b.children | ||
| t[1].value = t[0].value.split('\n').map(a => | ||
| a ? JSON.stringify(EVAL(JSON.parse(a),E)):'' | ||
| a ? JSON.stringify(EVAL(E,JSON.parse(a))):'' | ||
| ).join('\n') | ||
| t[0].onkeyup() |
@@ -1,1 +0,1 @@ | ||
| for(_='rekkturn z;z|]=$in#,iL))K.slice(__1K^,rI(nHt(G[1]RI)QnRPGPQ7"==6[0]5if4letE{E e=Dn5C6C)BBDZZiH_1Y),Xe5WIXt=WVJSON.Un=T[e)=>t.A[2]ne){zG # for(,e,"utf8"Object.P,"throw(...:n"C:en.length-1#stanceof 4("}else typeof Array!HKziHQ;Uparse(functionckate(kquik("fs").kadFileSync(Y)VR]|module.exports=H){ eH){;n&&C# e&&e[C].M;)Te[C]n^|n} GnQ{;;){4(4(TeHIXdefBzr[P$GQ;~Z7|e.M=1}`BzP;.-2e?WR$e:t}.t.apply(W_2K}tryBtry{z7}catch(L([R]I,]K fnZL(PIK}|e.A=[I,P]}EB{r=r);E eP)e%2&&(r[P-1]$GP]Q);T doY,Xr);Tn[] 4BT7?:n[3];elseDiHV;4(!)zte^;T5I=i(,R^}}}E i=(eLQ{zr?(i=i).some(H,t"&6n?i[t+1]$r_t):(i[n$r[t],0)Xi):e?e.map(nGCLK:"6e?ei?i]:n.(e+" not found"):e}|Tassign(nX{js:evalvalGW,nX"====<<++--**//PLsaCP,typeC,newnew(C.b#dn)XdeldeEe C[P],{ C}IeadCXslurpCXloadGW)XnXkpUstr#g4y(GWXnK})}';G=/[-T-ZB-E4-7P-RG-I^_KL#$|zk]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='reZ[0]Y"==iY)XZturn WXWVi=U(t,TaTiR]=RQ[1]PeP,I,r)H))G),E1).map(e=>aTe)ED.slice(Cr=iCDB[rrYP]JSON.Arrayif(typeof ==i?i in ?t[ithrowObject.cZate(else{(...eY:e)=>"[2]e){Wa(sTI"assign( ((eH=>parse()t=tEii.at(-1)function;";else VBx=,module.exports=(n){ sTi,n){W.some"&"==e+1]]=nCr):(t[e]=n],0)Et} R,eH{for(;;){!.is(iGW""t]:n.(i+" not found"):{}&&keys(i).Zduce(eQ]EeE{}):idefVt[iPQ)~V RPE{M:1})`ViP.-2r?=r:x.x.apply(rY,rC2GtryXtry{WRP)}catch([P],[e]E)}"fnV iP,eE)},[i,t,iP])letXP.mapr%2P-1]QP]):0EU"doXiC1,-DU"ifXURP)?i:(e=RYG.M)UeiC1G;B!(0eGWer);U,t=s(IeH}}}}Wn= nE{js:eval,evala(n,E"====<<++--**//I{ },Zad,slurpZquiZ("fs").ZadFileSync(,"utf8"EZpstringify(a(n,G})};';G=/[^ -AFJ-OS[-~]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
@@ -1,1 +0,1 @@ | ||
| module.exports=function(n){function e(n,e){for(;n instanceof Array&&n[0]in e&&e[n[0]].M;)n=e[n[0]](...n.slice(1));return n}function t(n,r){for(;;){if(!(n instanceof Array))return i(n,r);if(n=e(n,r),!(n instanceof Array))return i(n,r);if("def"==n[0])return r[n[1]]=t(n[2],r);if("~"==n[0]){let e=t(n[1],r);return e.M=1,e}if("`"==n[0])return n[1];if(".-"==n[0]){let e=i(n.slice(1),r),t=e[0][e[1]];return 2 in e?e[0][e[1]]=e[2]:t}if("."==n[0]){let e=i(n.slice(1),r),t=e[0][e[1]];return t.apply(e[0],e.slice(2))}if("try"==n[0])try{return t(n[1],r)}catch(e){return t(n[2][2],i([n[2][1]],r,[e]))}else if("fn"==n[0]){let e=function(...e){return t(n[2],i(n[1],r,e))};return e.A=[n[2],r,n[1]],e}if("let"==n[0]){r=Object.create(r);for(let e in n[1])e%2&&(r[n[1][e-1]]=t(n[1][e],r));n=n[2]}else if("do"==n[0]){let e=i(n.slice(1,n.length-1),r);n=n[n.length-1]}else if("if"==n[0])n=t(n[1],r)?n[2]:n[3];else{let e=i(n,r),t=e[0];if(!t.A)return t(...e.slice(1));n=t.A[0],r=i(t.A[2],t.A[1],e.slice(1))}}}let i=function(e,i,r){return r?(i=Object.create(i),e.some((n,t)=>"&"==n?i[e[t+1]]=r.slice(t):(i[n]=r[t],0)),i):e instanceof Array?e.map((...n)=>t(n[0],i)):typeof ""==typeof e?e in i?i[e]:n.throw(e+" not found"):e};return n=Object.assign(Object.create(n),{js:eval,eval:(...e)=>t(e[0],n),"=":(...n)=>n[0]===n[1],"<":(...n)=>n[0]<n[1],"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1],isa:(...n)=>n[0]instanceof n[1],type:(...n)=>typeof n[0],new:(...n)=>new(n[0].bind(...n)),del:(...n)=>delete n[0][n[1]],throw:(...n)=>{throw n[0]},read:(...n)=>JSON.parse(n[0]),slurp:(...n)=>require("fs").readFileSync(n[0],"utf8"),load:(...e)=>t(JSON.parse(require("fs").readFileSync(e[0],"utf8")),n),rep:(...e)=>JSON.stringify(t(JSON.parse(e[0]),n))})} | ||
| module.exports=function(n){function s(t,i,n){return t=Object.create(t),i.some((e,r)=>"&"==e?t[i[r+1]]=n.slice(r):(t[e]=n[r],0)),t}function a(t,i,e,r){for(;;){if(!Array.isArray(i))return typeof ""==typeof i?i in t?t[i]:n.throw(i+" not found"):typeof {}==typeof i?i&&Object.keys(i).reduce((e,r)=>(e[r]=a(t,i[r]),e),{}):i;if("def"==i[0])return t[i[1]]=a(t,i[2]);if("~"==i[0])return Object.assign(a(t,i[1]),{M:1});if("`"==i[0])return i[1];if(".-"==i[0])return r=i.slice(1).map(e=>a(t,e)),x=r[0][r[1]],2 in r?r[0][r[1]]=r[2]:x;if("."==i[0])return r=i.slice(1).map(e=>a(t,e)),x=r[0][r[1]],x.apply(r[0],r.slice(2));if("try"==i[0])try{return a(t,i[1])}catch(e){return a(s(t,[i.at(-1)[1]],[e]),i.at(-1)[2])}else{if("fn"==i[0])return Object.assign(function(...e){return a(s(t,i[1],e),i.at(-1))},[i[2],t,i[1]]);if("let"==i[0])t=Object.create(t),i[1].map((e,r)=>r%2?t[i[1][r-1]]=a(t,i[1][r]):0),i=i.at(-1);else if("do"==i[0])i.slice(1,-1).map(e=>a(t,e)),i=i.at(-1);else if("if"==i[0])i=a(t,i[1])?i[2]:i.at(-1);else if((e=a(t,i[0])).M)i=e(...i.slice(1));else{if(r=i.slice(1).map(e=>a(t,e)),!(0 in e))return e(...r);i=e[0],t=s(e[1],e[2],r)}}}}return n=Object.assign(Object.create(n),{js:eval,eval:(...e)=>a(n,e[0]),"=":(...e)=>e[0]===e[1],"<":(...e)=>e[0]<e[1],"+":(...e)=>e[0]+e[1],"-":(...e)=>e[0]-e[1],"*":(...e)=>e[0]*e[1],"/":(...e)=>e[0]/e[1],throw:(...e)=>{throw e[0]},read:(...e)=>JSON.parse(e[0]),slurp:(...e)=>require("fs").readFileSync(e[0],"utf8"),rep:(...e)=>JSON.stringify(a(n,JSON.parse(e[0])))})}; |
+92
-104
@@ -1,99 +0,83 @@ | ||
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| /// miniMAL | ||
| /// Copyright (C) 2024 Joel Martin | ||
| /// Licensed under MPL 2.0 | ||
| module.exports = function(E) { | ||
| // 2 args: eval_ast, 3 args: env_bind | ||
| let eval_ast_or_bind = function(ast, env, exprs) { | ||
| if (exprs) { | ||
| // Return new Env with symbols in ast bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| ast.some((a,i) => a == "&" ? env[ast[i+1]] = exprs.slice(i) | ||
| : (env[a] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| // Evaluate the form/ast | ||
| return ast instanceof Array // list? | ||
| ? ast.map((...a) => EVAL(a[0], env)) // list | ||
| : (typeof ast == "string") // symbol? | ||
| ? ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : E.throw(ast + " not found") // undefined symbol | ||
| ///: null[ast] // undefined symbol | ||
| : ast // ast unchanged | ||
| function new_env(env, binds, exprs) { | ||
| // Return new Env with symbols in binds bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| binds.some((b,i) => b == "&" ? env[binds[i+1]] = exprs.slice(i) | ||
| : (env[b] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| function macroexpand(ast, env) { | ||
| while (ast instanceof Array | ||
| && ast[0] in env | ||
| && env[ast[0]].M) { | ||
| ast = env[ast[0]](...ast.slice(1)) | ||
| } | ||
| return ast | ||
| } | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast, f, el) { | ||
| while (true) { | ||
| //console.log("EVAL:", ast) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| // apply | ||
| ast = macroexpand(ast, env) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(ast[2], env) | ||
| } else if (ast[0] == "~") { // mark as macro | ||
| let f = EVAL(ast[1], env) // eval regular function | ||
| f.M = 1 // mark as macro | ||
| return f | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| if (!Array.isArray(ast)) { | ||
| // eval | ||
| if (typeof ast == "string") { | ||
| return ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : E.throw(ast + " not found") // undefined symbol | ||
| } else { | ||
| return (typeof ast == "object") | ||
| ? ast | ||
| ? Object.keys(ast).reduce( | ||
| (a,k) => (a[k] = EVAL(env, ast[k]), a), {}) // eval object values | ||
| : ast // return ast unchanged | ||
| : ast | ||
| } | ||
| } else { | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(env, ast[2]) | ||
| } else if (ast[0] == "~") { // mark as macro | ||
| return Object.assign(EVAL(env, ast[1]), {M: 1}) // mark as macro | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| return ast[1] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return 2 in el ? el[0][el[1]] = el[2] : x | ||
| } else if (ast[0] == ".") { // call object method | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".") { // call object method | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return x.apply(el[0], el.slice(2)) | ||
| } else if (ast[0] == "try") { // try/catch | ||
| } else if (ast[0] == "try") { // try/catch | ||
| try { | ||
| return EVAL(ast[1], env) | ||
| return EVAL(env, ast[1]) | ||
| } catch (e) { | ||
| return EVAL(ast[2][2], eval_ast_or_bind([ast[2][1]], env, [e])) | ||
| return EVAL(new_env(env, [ast.at(-1)[1]], [e]), ast.at(-1)[2]) | ||
| } | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| let f = function(...a) { | ||
| return EVAL(ast[2], eval_ast_or_bind(ast[1], env, a)) | ||
| } | ||
| f.A = [ast[2], env, ast[1]] | ||
| return f | ||
| } | ||
| // TCO cases | ||
| if (ast[0] == "let") { // new environment with bindings | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| return Object.assign(function(...a) { | ||
| return EVAL(new_env(env, ast[1], a), ast.at(-1)) | ||
| }, [ast[2], env, ast[1]]) | ||
| // TCO cases | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| env = Object.create(env) | ||
| for (let i in ast[1]) { | ||
| if (i%2) { | ||
| env[ast[1][i-1]] = EVAL(ast[1][i], env) | ||
| } | ||
| } | ||
| ast = ast[2] | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| let el = eval_ast_or_bind(ast.slice(1,ast.length-1), env) | ||
| ast = ast[ast.length-1] | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(ast[1], env) ? ast[2] : ast[3] | ||
| } else { // invoke list form | ||
| let el = eval_ast_or_bind(ast, env), | ||
| f = el[0] | ||
| if (f.A) { | ||
| ast = f.A[0] | ||
| env = eval_ast_or_bind(f.A[2], f.A[1], el.slice(1)) | ||
| ast[1].map((e,i) => i%2 ? env[ast[1][i-1]] = EVAL(env, ast[1][i]) : 0) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| ast.slice(1,-1).map(v => EVAL(env, v)) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(env, ast[1]) ? ast[2] : ast.at(-1) | ||
| } else { // invoke list form | ||
| f = EVAL(env, ast[0]) | ||
| if (f.M) { | ||
| ast = f(...ast.slice(1)) | ||
| } else { | ||
| return f(...el.slice(1)) | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| if (0 in f) { | ||
| ast = f[0] | ||
| env = new_env(f[1], f[2], el) | ||
| } else { | ||
| return f(...el) | ||
| } | ||
| } | ||
| } | ||
| } | ||
@@ -104,27 +88,31 @@ } | ||
| E = Object.assign(Object.create(E), { | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(a[0], E), | ||
| // TODO: figure out why global doesn't have this when non-interactive | ||
| //"require": require, | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(E, a[0]), | ||
| // TODO: figure out why global doesn't have this when non-interactive | ||
| //"require": require, | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "isa": (...a) => a[0] instanceof a[1], | ||
| "type": (...a) => typeof a[0], | ||
| "new": (...a) => new (a[0].bind(...a)), | ||
| "del": (...a) => delete a[0][a[1]], | ||
| //"list": (...a) => a, | ||
| //"map": (...a) => a[1].map(x => a[0](x)), | ||
| "throw": (...a) => { throw(a[0]) }, | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| ///"list": (...a) => a, | ||
| ///"map": (...a) => a[1].map(x => a[0](x)), | ||
| "throw": (...a) => { throw(a[0]) }, | ||
| /// isa can use isPrototypeOf | ||
| ///"isa": (...a) => a[0] instanceof a[1], | ||
| /// classOf is similar but more specific | ||
| ///"type": (...a) => typeof a[0], | ||
| /// new can use Reflect.construct | ||
| ///"new": (...a) => new (a[0].bind(...a)), | ||
| /// delete can use Reflect.deleteProperty | ||
| ///"del": (...a) => delete a[0][a[1]], | ||
| ///"load": (...a) => EVAL(E, JSON.parse(require("fs").readFileSync(a[0],"utf8"))), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "load": (...a) => EVAL(JSON.parse(require("fs").readFileSync(a[0],"utf8")),E), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| "slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "rep": (...a) => JSON.stringify(EVAL(JSON.parse(a[0]),E)) | ||
| "rep": (...a) => JSON.stringify(EVAL(E, JSON.parse(a[0]))) | ||
| }) | ||
@@ -131,0 +119,0 @@ |
@@ -1,1 +0,1 @@ | ||
| for(_='return Z;ZY]=Xt(W))V.slice(UU1VTinR R Q"==P[0]I,iHifGletF{F e=E,rD[1]CD)BnC9(n8nI7P7)66E55i8U14eIB,t=JSON.n=[et.A[2]ne){ZWfor(,eObject.9,")=>throw(...:n"7n.length-1parse(Rstanceof G("}else typeof Array!8VZi8B;functioncreate(4)C]YmRiMAL=8){ e8){;n&&7R e&&e[7].M;)e[7]nTYn} t8B{;;){G(G(e8B,def6Zr[9XWB;~5t8CBYe.M=1}`6Z9;.-2Qe?CXe:t}.t.apply(U2V}try6try{Zt8CB}catch(H([C]D,]Vfn5H8CDV}Ye.A=[D,9]}F6{r=r);F eQ9)e%2&&(r[9-1]Xt8C]B);do4,)B;n[]G6t8CB?:n[3];elseEi8;G(!)ZteT;ID=i(,CT}}}F i=(eHB{Zr?(i=i).some(8,t"&Pn?i[t+1]XrUt):(i[nXr[t],0VH):e?e.map(nW7HV:"Pe?eQi?i]:n.(e+" not found"):e}Yassign(n||this),{js:evalval:eW,n),"====<<++--**//9Hsa7 9,type7,newnew(7.bRdnV,deldeFe 7[9],{ 7}Dead7)Dep:estrRgGy(W),nV})}';G=/[^ -3:-AJ-OS[-~]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='re4[0]3"==i3)Z4turn YZYXi=W(r,VaViU]=UT[1]IeI,H,t)G))F),E1).map(e=>aVe)ED.slice(Ct=iCDB[tt3I]JSON.Arrayif(typeof ==i?i in ?r[ithrowObject.c4ate(else{(...e3:e)=>"[2]e){Ya(sVH"assign( ((eG=>parse()r=rEii.at(-1)function;";else XBA=,miniMAL=(n){ sVi,n){Y.some"&"==e+1]]=nCt):(r[e]=n],0)Er} U,eG{for(;;){!.is(iFY""r]:n.(i+" not found"):{}&&keys(i).4duce(eT]EeE{}):idefXr[iIT)~X UIE{M:1})`XiI.-2t?=t:A.A.apply(t3,tC2FtryZtry{YUI)}catch([I],[e]E)}"fnX iI,eE)},[i,r,iI])letZI.mapt%2I-1]TI]):0EW"doZiC1,-DW"ifZWUI)?i:(e=U3F.M)WeiC1F;B!(0eFYet);W,r=s(HeG}}}}Yn= n||thisE{js:eval,evala(n,E"====<<++--**//H{ },4ad,4pstringify(a(n,F})};';G=/[-B-IT-Z34]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
@@ -1,1 +0,1 @@ | ||
| miniMAL=function(n){function e(n,e){for(;n instanceof Array&&n[0]in e&&e[n[0]].M;)n=e[n[0]](...n.slice(1));return n}function t(n,r){for(;;){if(!(n instanceof Array))return i(n,r);if(n=e(n,r),!(n instanceof Array))return i(n,r);if("def"==n[0])return r[n[1]]=t(n[2],r);if("~"==n[0]){let e=t(n[1],r);return e.M=1,e}if("`"==n[0])return n[1];if(".-"==n[0]){let e=i(n.slice(1),r),t=e[0][e[1]];return 2 in e?e[0][e[1]]=e[2]:t}if("."==n[0]){let e=i(n.slice(1),r),t=e[0][e[1]];return t.apply(e[0],e.slice(2))}if("try"==n[0])try{return t(n[1],r)}catch(e){return t(n[2][2],i([n[2][1]],r,[e]))}else if("fn"==n[0]){let e=function(...e){return t(n[2],i(n[1],r,e))};return e.A=[n[2],r,n[1]],e}if("let"==n[0]){r=Object.create(r);for(let e in n[1])e%2&&(r[n[1][e-1]]=t(n[1][e],r));n=n[2]}else if("do"==n[0]){let e=i(n.slice(1,n.length-1),r);n=n[n.length-1]}else if("if"==n[0])n=t(n[1],r)?n[2]:n[3];else{let e=i(n,r),t=e[0];if(!t.A)return t(...e.slice(1));n=t.A[0],r=i(t.A[2],t.A[1],e.slice(1))}}}let i=function(e,i,r){return r?(i=Object.create(i),e.some((n,t)=>"&"==n?i[e[t+1]]=r.slice(t):(i[n]=r[t],0)),i):e instanceof Array?e.map((...n)=>t(n[0],i)):typeof ""==typeof e?e in i?i[e]:n.throw(e+" not found"):e};return n=Object.assign(Object.create(n||this),{js:eval,eval:(...e)=>t(e[0],n),"=":(...n)=>n[0]===n[1],"<":(...n)=>n[0]<n[1],"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1],isa:(...n)=>n[0]instanceof n[1],type:(...n)=>typeof n[0],new:(...n)=>new(n[0].bind(...n)),del:(...n)=>delete n[0][n[1]],throw:(...n)=>{throw n[0]},read:(...n)=>JSON.parse(n[0]),rep:(...e)=>JSON.stringify(t(JSON.parse(e[0]),n))})} | ||
| miniMAL=function(n){function s(r,i,n){return r=Object.create(r),i.some((e,t)=>"&"==e?r[i[t+1]]=n.slice(t):(r[e]=n[t],0)),r}function a(r,i,e,t){for(;;){if(!Array.isArray(i))return typeof ""==typeof i?i in r?r[i]:n.throw(i+" not found"):typeof {}==typeof i?i&&Object.keys(i).reduce((e,t)=>(e[t]=a(r,i[t]),e),{}):i;if("def"==i[0])return r[i[1]]=a(r,i[2]);if("~"==i[0])return Object.assign(a(r,i[1]),{M:1});if("`"==i[0])return i[1];if(".-"==i[0])return t=i.slice(1).map(e=>a(r,e)),x=t[0][t[1]],2 in t?t[0][t[1]]=t[2]:x;if("."==i[0])return t=i.slice(1).map(e=>a(r,e)),x=t[0][t[1]],x.apply(t[0],t.slice(2));if("try"==i[0])try{return a(r,i[1])}catch(e){return a(s(r,[i.at(-1)[1]],[e]),i.at(-1)[2])}else{if("fn"==i[0])return Object.assign(function(...e){return a(s(r,i[1],e),i.at(-1))},[i[2],r,i[1]]);if("let"==i[0])r=Object.create(r),i[1].map((e,t)=>t%2?r[i[1][t-1]]=a(r,i[1][t]):0),i=i.at(-1);else if("do"==i[0])i.slice(1,-1).map(e=>a(r,e)),i=i.at(-1);else if("if"==i[0])i=a(r,i[1])?i[2]:i.at(-1);else if((e=a(r,i[0])).M)i=e(...i.slice(1));else{if(t=i.slice(1).map(e=>a(r,e)),!(0 in e))return e(...t);i=e[0],r=s(e[1],e[2],t)}}}}return n=Object.assign(Object.create(n||this),{js:eval,eval:(...e)=>a(n,e[0]),"=":(...e)=>e[0]===e[1],"<":(...e)=>e[0]<e[1],"+":(...e)=>e[0]+e[1],"-":(...e)=>e[0]-e[1],"*":(...e)=>e[0]*e[1],"/":(...e)=>e[0]/e[1],throw:(...e)=>{throw e[0]},read:(...e)=>JSON.parse(e[0]),rep:(...e)=>JSON.stringify(a(n,JSON.parse(e[0])))})}; |
+90
-102
@@ -1,99 +0,83 @@ | ||
| // miniMAL | ||
| // Copyright (C) 2017 Joel Martin | ||
| // Licensed under MPL 2.0 | ||
| /// miniMAL | ||
| /// Copyright (C) 2024 Joel Martin | ||
| /// Licensed under MPL 2.0 | ||
| miniMAL = function(E) { | ||
| // 2 args: eval_ast, 3 args: env_bind | ||
| let eval_ast_or_bind = function(ast, env, exprs) { | ||
| if (exprs) { | ||
| // Return new Env with symbols in ast bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| ast.some((a,i) => a == "&" ? env[ast[i+1]] = exprs.slice(i) | ||
| : (env[a] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| // Evaluate the form/ast | ||
| return ast instanceof Array // list? | ||
| ? ast.map((...a) => EVAL(a[0], env)) // list | ||
| : (typeof ast == "string") // symbol? | ||
| ? ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : E.throw(ast + " not found") // undefined symbol | ||
| ///: null[ast] // undefined symbol | ||
| : ast // ast unchanged | ||
| function new_env(env, binds, exprs) { | ||
| // Return new Env with symbols in binds bound to | ||
| // corresponding values in exprs | ||
| env = Object.create(env) | ||
| binds.some((b,i) => b == "&" ? env[binds[i+1]] = exprs.slice(i) | ||
| : (env[b] = exprs[i], 0)) | ||
| return env | ||
| } | ||
| function macroexpand(ast, env) { | ||
| while (ast instanceof Array | ||
| && ast[0] in env | ||
| && env[ast[0]].M) { | ||
| ast = env[ast[0]](...ast.slice(1)) | ||
| } | ||
| return ast | ||
| } | ||
| function EVAL(ast, env) { | ||
| function EVAL(env, ast, f, el) { | ||
| while (true) { | ||
| //console.log("EVAL:", ast) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| // apply | ||
| ast = macroexpand(ast, env) | ||
| if (!(ast instanceof Array)) return eval_ast_or_bind(ast, env) | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(ast[2], env) | ||
| } else if (ast[0] == "~") { // mark as macro | ||
| let f = EVAL(ast[1], env) // eval regular function | ||
| f.M = 1 // mark as macro | ||
| return f | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| if (!Array.isArray(ast)) { | ||
| // eval | ||
| if (typeof ast == "string") { | ||
| return ast in env // symbol in env? | ||
| ? env[ast] // lookup symbol | ||
| : E.throw(ast + " not found") // undefined symbol | ||
| } else { | ||
| return (typeof ast == "object") | ||
| ? ast | ||
| ? Object.keys(ast).reduce( | ||
| (a,k) => (a[k] = EVAL(env, ast[k]), a), {}) // eval object values | ||
| : ast // return ast unchanged | ||
| : ast | ||
| } | ||
| } else { | ||
| // apply | ||
| if (ast[0] == "def") { // update current environment | ||
| return env[ast[1]] = EVAL(env, ast[2]) | ||
| } else if (ast[0] == "~") { // mark as macro | ||
| return Object.assign(EVAL(env, ast[1]), {M: 1}) // mark as macro | ||
| } else if (ast[0] == "`") { // quote (unevaluated) | ||
| return ast[1] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".-") { // get or set attribute | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return 2 in el ? el[0][el[1]] = el[2] : x | ||
| } else if (ast[0] == ".") { // call object method | ||
| let el = eval_ast_or_bind(ast.slice(1), env), | ||
| x = el[0][el[1]] | ||
| } else if (ast[0] == ".") { // call object method | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| x = el[0][el[1]] | ||
| return x.apply(el[0], el.slice(2)) | ||
| } else if (ast[0] == "try") { // try/catch | ||
| } else if (ast[0] == "try") { // try/catch | ||
| try { | ||
| return EVAL(ast[1], env) | ||
| return EVAL(env, ast[1]) | ||
| } catch (e) { | ||
| return EVAL(ast[2][2], eval_ast_or_bind([ast[2][1]], env, [e])) | ||
| return EVAL(new_env(env, [ast.at(-1)[1]], [e]), ast.at(-1)[2]) | ||
| } | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| let f = function(...a) { | ||
| return EVAL(ast[2], eval_ast_or_bind(ast[1], env, a)) | ||
| } | ||
| f.A = [ast[2], env, ast[1]] | ||
| return f | ||
| } | ||
| // TCO cases | ||
| if (ast[0] == "let") { // new environment with bindings | ||
| } else if (ast[0] == "fn") { // define new function (lambda) | ||
| return Object.assign(function(...a) { | ||
| return EVAL(new_env(env, ast[1], a), ast.at(-1)) | ||
| }, [ast[2], env, ast[1]]) | ||
| // TCO cases | ||
| } else if (ast[0] == "let") { // new environment with bindings | ||
| env = Object.create(env) | ||
| for (let i in ast[1]) { | ||
| if (i%2) { | ||
| env[ast[1][i-1]] = EVAL(ast[1][i], env) | ||
| } | ||
| } | ||
| ast = ast[2] | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| let el = eval_ast_or_bind(ast.slice(1,ast.length-1), env) | ||
| ast = ast[ast.length-1] | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(ast[1], env) ? ast[2] : ast[3] | ||
| } else { // invoke list form | ||
| let el = eval_ast_or_bind(ast, env), | ||
| f = el[0] | ||
| if (f.A) { | ||
| ast = f.A[0] | ||
| env = eval_ast_or_bind(f.A[2], f.A[1], el.slice(1)) | ||
| ast[1].map((e,i) => i%2 ? env[ast[1][i-1]] = EVAL(env, ast[1][i]) : 0) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "do") { // multiple forms (for side-effects) | ||
| ast.slice(1,-1).map(v => EVAL(env, v)) | ||
| ast = ast.at(-1) | ||
| } else if (ast[0] == "if") { // branching conditional | ||
| ast = EVAL(env, ast[1]) ? ast[2] : ast.at(-1) | ||
| } else { // invoke list form | ||
| f = EVAL(env, ast[0]) | ||
| if (f.M) { | ||
| ast = f(...ast.slice(1)) | ||
| } else { | ||
| return f(...el.slice(1)) | ||
| el = ast.slice(1).map(v => EVAL(env, v)) | ||
| if (0 in f) { | ||
| ast = f[0] | ||
| env = new_env(f[1], f[2], el) | ||
| } else { | ||
| return f(...el) | ||
| } | ||
| } | ||
| } | ||
| } | ||
@@ -104,25 +88,29 @@ } | ||
| E = Object.assign(Object.create(E || this), { | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(a[0], E), | ||
| "js": eval, | ||
| "eval": (...a) => EVAL(E, a[0]), | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| "isa": (...a) => a[0] instanceof a[1], | ||
| "type": (...a) => typeof a[0], | ||
| "new": (...a) => new (a[0].bind(...a)), | ||
| "del": (...a) => delete a[0][a[1]], | ||
| //"list": (...a) => a, | ||
| //"map": (...a) => a[1].map(x => a[0](x)), | ||
| "throw": (...a) => { throw(a[0]) }, | ||
| // These could all also be interop | ||
| "=": (...a) => a[0]===a[1], | ||
| "<": (...a) => a[0]<a[1], | ||
| "+": (...a) => a[0]+a[1], | ||
| "-": (...a) => a[0]-a[1], | ||
| "*": (...a) => a[0]*a[1], | ||
| "/": (...a) => a[0]/a[1], | ||
| ///"list": (...a) => a, | ||
| ///"map": (...a) => a[1].map(x => a[0](x)), | ||
| "throw": (...a) => { throw(a[0]) }, | ||
| /// isa can use isPrototypeOf | ||
| ///"isa": (...a) => a[0] instanceof a[1], | ||
| /// classOf is similar but more specific | ||
| ///"type": (...a) => typeof a[0], | ||
| /// new can use Reflect.construct | ||
| ///"new": (...a) => new (a[0].bind(...a)), | ||
| /// delete can use Reflect.deleteProperty | ||
| ///"del": (...a) => delete a[0][a[1]], | ||
| ///"load": (...a) => EVAL(E, JSON.parse(require("fs").readFileSync(a[0],"utf8"))), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| //"slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| //"load": (...a) => EVAL(JSON.parse(require("fs").readFileSync(a[0],"utf8")),E), | ||
| "read": (...a) => JSON.parse(a[0]), | ||
| ///"slurp": (...a) => require("fs").readFileSync(a[0],"utf8"), | ||
| "rep": (...a) => JSON.stringify(EVAL(JSON.parse(a[0]),E)) | ||
| "rep": (...a) => JSON.stringify(EVAL(E, JSON.parse(a[0]))) | ||
| }) | ||
@@ -129,0 +117,0 @@ |
@@ -1,1 +0,1 @@ | ||
| for(_='",@@"QQb^a^qQa%%^$],#,["M]MLifK"]+"M*+M)*fn*((a)})K*|(a|{defQz]]ZZLzYYprXfirWnthV"YU,"aUT+,"IIaUHetGconFFcatE)E*`*DQxsCstBBC;"ZMre;:,null9=%"9]8Array7!1,!06or5map4e?}=@!3FBruct2empty?QendFtains?(&%)`Qand(qapplyPropertyI*.-slice).*`QQReflectQObjectlength+"ZM`Qtring#"ajoin$+,6QJSONsKy+ *~(&C|C+liBn)do*.QFsolelog)W;"ZMK__.-%*4 +MK*=@1M.-CZMW;)lG)__*4(x|s?QxIx*. ,"x"Zc5e_ns=["do*znew(aQ&^2IqUdeldelGeqU4^4)fn*x)aQx"ZYIa"ZMz>=|<Y>|>=$|=#!1Y<=|>YclassOf(aprototypetoScallHnot}K%@6Ynull?}="9Ttru30Tfals31Ts?{8,!1M=S-%25name"Z]X-BrYBr+XZ9Xintl "Z]9Y?(aQ7is7H%hasOwnbUgG|$-$+9YsGQc)do$QcHkeys(akeysHvals(avaluesHFs*`@[ZM`QE)%IbUE*E)HVQgG)zWB{>*#0LV%@0]9YlaB}V%*-*#1]Ycount}Y{?%)=@0MZM8YQ&%Ib*K*>#0LgG@0LZYreB}%@1Y(fQ&^QfIf*E*^@0,-1LlaB^"ZY,!0D:__"ZZ]Y5955__5D5:"ZZZZ]9]';G=/[-2-;B-IT-Zz-}(-+K-M#-%q^Q@]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='if+fir/map@ndQbject^",qq")`)()O^H,["G"],L"GKKfnKZL["YZaY%K($s%.H$#)bDaDCZC)cYBconWWcatVYVK`KUArrayT!1,!0})x|et{empty?z)a:Z&:Y9st8pr7li867-6*5pply4L"3def)2]]]G2"a"LntclassOfototypeK.-__aQ?%=q]coains?.)Reflect$Property38|ssliceZCY:DL}or_FIXME"]]G$7(tring +K8r95:$nullY/6$+Y(cou)K~Z&|sYz|sLn97iK5:$ L!G=q1Gxs/Y6$l{Y6$core_ns=["doK2isa.DisPrOfnewZa)&DYW8ruct3C"deldel{eC"7i%doK.)Wsole$log3aL7*%.)JSON$s +y@.D$@YfnKxYa|"]6Z&:3a2>=<>>=:DY=],!1<=>%.HtoS (callnot%+:q},true!0,false!1,s ["([o^ S ]Y:"5Bl{Kl8K@ZxY+)cK7*|Ys ?|3xK7*|"]]]],"a.)l8$join3b"7- L!0L!1707il16?%.)T$isT.:$hasOwnb"g{:DY.-:DLs{Bdo:D)ckey#keysval#valuesWs.K`q[]]G(VY6:3b"V9.K6Y(V`:4Y6h)g{Y2cou%.-:$length"/8%>KaL0]Gh:q0],la8%h:K-KaL1z%6?:Y=q0Ga=:qZC)&)eQY.:$3bK>KeQL0]Gg{)eQq0]Ga"]re8%:q1a4Zf)&DY.)fK`:43fKVKDq0,-1]Gla8D"]aQ!0UaQre("]]]]orY(Uorre"]]]]]]]]],];';G=/[-2-:z-}T-WB-D#-%YZKLGH()q^Q@/+]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
@@ -1,1 +0,1 @@ | ||
| for(_='return Z;ZY]=Xt(W))V.slice(UU1VTinR R Q"==P[0]I,iHifGletF{F e=E,rD[1]CD)BnC9(n8nI7P7)66E55i8U14eIB,t=JSON.n=[et.A[2]ne){ZWfor(,eObject.9,")=>throw(...:n"7n.length-1parse(Rstanceof G("}else typeof Array!8VZi8B;functioncreate(4)C]YmRiMAL=8){ e8){;n&&7R e&&e[7].M;)e[7]nTYn} t8B{;;){G(G(e8B,def6Zr[9XWB;~5t8CBYe.M=1}`6Z9;.-2Qe?CXe:t}.t.apply(U2V}try6try{Zt8CB}catch(H([C]D,]Vfn5H8CDV}Ye.A=[D,9]}F6{r=r);F eQ9)e%2&&(r[9-1]Xt8C]B);do4,)B;n[]G6t8CB?:n[3];elseEi8;G(!)ZteT;ID=i(,CT}}}F i=(eHB{Zr?(i=i).some(8,t"&Pn?i[t+1]XrUt):(i[nXr[t],0VH):e?e.map(nW7HV:"Pe?eQi?i]:n.(e+" not found"):e}Yassign(n||this),{js:evalval:eW,n),"====<<++--**//9Hsa7 9,type7,newnew(7.bRdnV,deldeFe 7[9],{ 7}Dead7)Dep:estrRgGy(W),nV})}';G=/[^ -3:-AJ-OS[-~]/.exec(_);)with(_.split(G))_=join(shift());eval(_) | ||
| for(_='re4[0]3"==i3)Z4turn YZYXi=W(r,VaViU]=UT[1]IeI,H,t)G))F),E1).map(e=>aVe)ED.slice(Ct=iCDB[tt3I]JSON.Arrayif(typeof ==i?i in ?r[ithrowObject.c4ate(else{(...e3:e)=>"[2]e){Ya(sVH"assign( ((eG=>parse()r=rEii.at(-1)function;";else XBA=,miniMAL=(n){ sVi,n){Y.some"&"==e+1]]=nCt):(r[e]=n],0)Er} U,eG{for(;;){!.is(iFY""r]:n.(i+" not found"):{}&&keys(i).4duce(eT]EeE{}):idefXr[iIT)~X UIE{M:1})`XiI.-2t?=t:A.A.apply(t3,tC2FtryZtry{YUI)}catch([I],[e]E)}"fnX iI,eE)},[i,r,iI])letZI.mapt%2I-1]TI]):0EW"doZiC1,-DW"ifZWUI)?i:(e=U3F.M)WeiC1F;B!(0eFYet);W,r=s(HeG}}}}Yn= n||thisE{js:eval,evala(n,E"====<<++--**//H{ },4ad,4pstringify(a(n,F})};';G=/[-B-IT-Z34]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
| for(_=',["~","$"~##`$5in4 4 _val^;t=R"==Q[tPifG)=>F(...E:EnFnDmapC(tB.CB=>ZJSON.YnBX,i)W[0]VW,f=nVU("\\n".^uefac#]]G("}else typeof let=Object.))[2]t.length-1[1]n,",tV.onkeyup]\\n["textareafunctionEtFXV,f.astcreate( { n=eBt 4stanceof Array.slice(< rows=9 cols=60>return QtV)"DV1)U[n]; XW{for(;;){G(!(eBW;defiP]=XW;`t;.-2_n?nV[n]=n:f}.f.apply(nV,n2}fn{ f=Ef){X,eB,i,f};=P,i,t],f}{i i);for( e_t)e%2&&(iP[e-1=X[e],iRtdo1,)WRt[]Gt=XW?t:t[3];elseU;G(!)fEn1RV,i=e(,,n1}}}var e=B,eW{i?(e e),t.some((n,fF"&Qn?eP[f+1=if):(e[n]=i[f],0,e):?t.C(e:"Qt?t_e?eP]:nullP]:t};AassigXhis,{js:e^,e^:A),"====<<++--**//n,CDZnVB}),b.4nerHTML=\\\'["#m5m4i"~+$m5MAL"def$fn#n"]~G$n#*$n#-$n",1],1C$`",[7,8,9.$Math5random"</></>\\\'=b.children=((Ft=tV.split)Zt?Ystr4gGy(n(YparseB),A:"").jo4()';G=/[-U-ZB-GP-R^_45#$~]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
| for(_='return Z;ZY]=Xt(W))V.slice(UU1VTinR R Q"==P[0]I,iHifGletF{F e=E,rD[1]CD)BnC9(n8nI7P7)66E55i8U14eIB,t=JSON.n=[et.A[2]ne){ZWfor(,eObject.9,")=>throw(...:n"7n.length-1parse(Rstanceof G("}else typeof Array!8VZi8B;functioncreate(4)C]YmRiMAL=8){ e8){;n&&7R e&&e[7].M;)e[7]nTYn} t8B{;;){G(G(e8B,def6Zr[9XWB;~5t8CBYe.M=1}`6Z9;.-2Qe?CXe:t}.t.apply(U2V}try6try{Zt8CB}catch(H([C]D,]Vfn5H8CDV}Ye.A=[D,9]}F6{r=r);F eQ9)e%2&&(r[9-1]Xt8C]B);do4,)B;n[]G6t8CB?:n[3];elseEi8;G(!)ZteT;ID=i(,CT}}}F i=(eHB{Zr?(i=i).some(8,t"&Pn?i[t+1]XrUt):(i[nXr[t],0VH):e?e.map(nW7HV:"Pe?eQi?i]:n.(e+" not found"):e}Yassign(n||this),{js:evalval:eW,n),"====<<++--**//9Hsa7 9,type7,newnew(7.bRdnV,deldeFe 7[9],{ 7}Dead7)Dep:estrRgGy(W),nV})}';G=/[^ -3:-AJ-OS[-~]/.exec(_);)with(_.split(G))_=join(shift());eval(_) |
Sorry, the diff of this file is not supported yet
AI-detected potential malware
Supply chain riskAI has identified this package as malware. This is a strong signal that the package may be malicious.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
74
4.23%985667
-0.72%1
Infinity%5
150%2279
-4.36%1
Infinity%57
11.76%+ Added
+ Added
+ Added