您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shirayuki language implement
当前为
// ==UserScript== // @name Shirayuki // @namespace // @version 1.13 // @description Shirayuki language implement // @author Rika // @match *://*.zhihu.com/* // @grant none // @require https://code.jquery.com/jquery-latest.js // @namespace https://gf.qytechs.cn/users/165948 // ==/UserScript== (function() { function interpreter(code_console){ this.code_console = code_console; this.halt = false; var self = this; function trampoline(f){ var func = f; while (typeof func === 'function') { func = func(); } return func; } function trampoline_exec(f){ var count = 0; while(count < (1 << 13) && typeof f === 'function') { count++; f = f(); } if (typeof f === 'function' && !self.halt) { setTimeout(trampoline_exec.bind(null, f), 0); } } function console_read(x){ self.code_console.input(x); } function console_write(x){ self.code_console.output(x); } function console_suspend(x){ self.code_console.suspend(x); } function console_clear(){ self.code_console.clear(); } function console_sleep(x,time){ self.code_console.sleep(x,time); } function toBoolean(x){ return Boolean(x)&&x!=false; } function isBoolean(x){ return typeof x === 'boolean'; } function isArray(x){ return Object.prototype.toString.call(x) === '[object Array]'; } function isNumber(x){ return !isNaN(x) && !isArray(x) &&x!=null; } function isString(x){ return typeof x === 'string' || x instanceof String; } function isFunction(x){ return typeof x === "function"; } function isEmpty(obj){ return jQuery.isEmptyObject(obj); } function nonEmpty(obj){ return !isEmpty(obj); } function set(x){ var ret={}; x.forEach(function(item,index){ret[item]=index;}); return ret; } function extend(obj, src){ for (var key in src) { if (src.hasOwnProperty(key) && !obj.hasOwnProperty(key)) obj[key] = src[key]; } return obj; } function map_cps(f,x,cont){ if(isEmpty(x)){ return cont.bind(null,[]); } else if(x.length==1){ return f.bind(null,x[0], function(y){ return cont.bind(null,[y]); }); } else{ return map_cps.bind(null,f,x.slice(0, x.length-1),function(y){ return f.bind(null, x[x.length-1], function(z){ y.push(z); return cont.bind(null,y); }); }); } } function filter_cps(f,x,cont){ if(isEmpty(x)){ return cont.bind(null,[]); } else if(x.length==1){ return f.bind(null, x[0], function(y){ if(y){ return cont.bind(null,[x[0]]); } else{ return cont.bind(null,[]); } }); } else{ return filter_cps.bind(null,f,x.slice(1),function(y){ return f.bind(null, x[0], function(z){ if(z){ y.unshift(x[0]); } return cont.bind(null,y); }); }); } } function reduce_cps(f,x,cont){ if(isEmpty(x)){ return cont.bind(null,[]); } else if(x.length==1){ return cont.bind(null,x[0]); } else if(x.length==2){ return f.bind(null,x[0],x[1],cont); } else{ return reduce_cps.bind(null,f,x.slice(1),function(y){ return f.bind(null,x[0], y, function(z){ return cont.bind(null,z); }); }); } } function argument_number(n) {return n>1 ? n + " arguments" : n + " argument";} function do_raise_syntax(msg){throw {name:'Error',message:'Syntax Error: '+msg+'.'}} function do_raise(msg){throw {name:'Error',message:'Running Error: '+msg+'.'}} var wapper=function(_f){ return function(){ return _f.apply(null, [wapper(_f)].concat(Array.prototype.slice.call(arguments))); } } var preprocessor_x=wapper( function(self,__Str,_n,_m,_k){ if(_n === undefined) { _n = 0; } if(_m === undefined) { _m = 0; } if(_k === undefined) { _k = 0; } return (!__Str && (_n==0 && _m==0 && _k==0)) ? '' : (!__Str) ? ( (_n!=0) ? do_raise_syntax("unmatched parentheses '"+(_n>0?'(':')')+"'") : (_m!=0) ? do_raise_syntax("unmatched parentheses '"+(_m>0?'{':'}')+"'") : do_raise_syntax("unmatched parentheses '"+(_k>0?'[':']')+"'") ) : (__Str[0]=='\n' && _n==0) ? '\n'+self(__Str.slice(1), _n) : (__Str[0]=='\n' && _n!=0) ? self(__Str.slice(1), _n) : (__Str[0].match(/[\w\d\+\-\*\/\%\.\(\)\^\!\<\>\=\:\,\t\|\{\}\[\]\\\~\ ]/)) ? __Str[0]+self(__Str.slice(1), _n+(__Str[0]=='(')-(__Str[0]==')'), _m+(__Str[0]=='{')-(__Str[0]=='}'), _k+(__Str[0]=='[')-(__Str[0]==']')) : do_raise_syntax("unexpect symbol '"+__Str[0]+"'"); }); var preprocessor=function(__Str){ return preprocessor_x(__Str.replace(/\/\/.*/g,'').replace(/[ \f\r\t\v]+/g,' ').split('\n').filter(function(x){return Boolean(x)}).join('\n')); } var lexer=function(__Str){ return (preprocessor(__Str).split(/(def!|\-\>|[<>=]{2}|\!\=|_(?=\s|\{|\()|\\(?:\(|\{)|(?:\)|\})\\|[\>\<\=\+\-\*\/\%\(\)\^\!\:\,\n\|\t\{\}\[\]\~\ ])/g).filter(function(c){return Boolean(c) && !(c in set([' ','\t']))}).map( function(s){ return (!isNaN(s) && s!='\n') ? Number(s) : (s=='<>') ? '!=' : (s.indexOf('.')==-1 || s=='=<' || s=='=>' || s=='><') ? s : do_raise_syntax("unexpect symbol '"+s+"'"); })); } var parser_unit=wapper( function(self,__List,__Level,__Escape){ var topLevel = 11; if(__Level === undefined) { __Level = topLevel; } if(__Escape === undefined) { __Escape = false; } return (__Level==0) ? ( (nonEmpty(__List) && (__List[0]=='(' || __List[0]=='{')) ? ( (function(_t){ return (_t.length>2 || _t[1][0]=='}') ? [['()', (_t.length>2 || _t[0]!=null) ? _t.slice(0,-1) : []], _t[_t.length-1].slice(1)] : [_t[0],_t[1].slice(1)]; })( wapper( function(self, rf, _t0){ return (nonEmpty(_t0[1]) && _t0[1][0]==',') ? (function(_tx){return [_t0[0]].concat(self(rf, _tx));})(rf(_t0[1].slice(1),topLevel,__Escape)): _t0; } )(self, self(__List.slice(1),topLevel,__Escape)) ) ) : (nonEmpty(__List) && (__List[0]=='\\(' || __List[0]=='\\{')) ? ( __Escape? ( (function(_t0){ return (isEmpty(_t0[1]) || (__List[0]=='\\(' && _t0[1][0]!=')\\') || (__List[0]=='\\{' && _t0[1][0]!='}\\')) ? do_raise_syntax("expect symbol '"+(__List[0]=='\\('?')\\':'}\\')+"', given: '"+_t0[1][0]+"'") : [[__List[0]+_t0[1][0],_t0[0]],_t0[1].slice(1)]; } )(self(__List.slice(1),topLevel,false))) : do_raise_syntax("unexpect symbol '"+__List[0]+"'") ): (nonEmpty(__List) && (__List[0]=='[')) ? ( (function(_t0){ return (isEmpty(_t0[1]) || _t0[1][0]!=']') ? do_raise_syntax("expect symbol ']', given: '"+_t0[1][0]+"'") : [['[]',_t0[0]],_t0[1].slice(1)]; } )(self(__List.slice(1),topLevel,true)) ) : (nonEmpty(__List) && (__List[0]=='~')) ? ( (function(_t){ return nonEmpty(_t) ? ( (function(_r){ return [[__List[0],_r[0]], _r[1]]; })(self(__List.slice(1),3,__Escape)) ) : do_raise_syntax("expect identifier, given: End of line") })(__List.slice(1)) ) : (nonEmpty(__List) && (isString(__List[0]) && __List[0]=='None')) ? ( [[__List[0]], __List.slice(1)] ) : (nonEmpty(__List) && (!isString(__List[0]) || !__List[0].match(/^(\-\>|\\(?:\(|\{)|(?:\)|\})\\|[<>=]{2}|[\>\<\=\,\+\-\*\/\%\(\)\^\!\|\{\}\[\]\_\:\~])$/))) ? ( [__List[0], __List.slice(1)] ) : [null, __List] ) : (__Level==1) ? ( (nonEmpty(__List) && __List[0] in set(['lambda','def','def!'])) ? ( (__List[0] in set(['def','def!']) && __Escape) ? do_raise_syntax("macro definitions are not allowed") : (function(_t){ return (nonEmpty(_t) && _t[0]==':') ? ( (function(sf,s0,s1,s2,t){ return sf(s2(s1(s0(t)))); }) ((function(_tf){ return [[((__List[0] in set(['def','def!']))&&_tf[0])?__List[0]+'_const':__List[0]].concat(_tf.slice(1,-1)),_tf[_tf.length-1]]; }), (function(_t0){ return (_t0.length>1 && _t0[0]!='\\(' && _t0[0]!='\\{' && _t0[1] in set(['=','('])) ? ( (!(_t0[0] in set(['None','lambda','def','def!','delay','callcc','eval','curry']))&&isString(_t0[0])&&_t0[0].match(/^[A-Za-z_][A-Za-z0-9_]*$/)) ? ([_t0[0],_t0.slice(1),_t0[1]=='=']) : do_raise_syntax("invaild "+((__List[0]=='lambda')?"function":"macro")+" name '"+_t0[0]+"'") ) : ((nonEmpty(_t0) && (_t0[0]=='\\(' || _t0[0]=='\\{')) ? ( (function(_tx){ return (nonEmpty(_tx[1]) && _tx[1][0] in set(['=','('])) ? [_tx[0],_tx[1],_t0[1][0]=='='] : ['',_t0,false]; })(self(_t0,0,__Escape)) ): ['',_t0,false]); }), (function(_t1){ return (!(__List[0]=='def' && isEmpty(_t1[0]))) ? _t1 : do_raise_syntax("anonymous macro"); }), (function(_t2){ return (function(_tc){ return [_t2[2],_t2[0],_tc[0]].concat( (_t2[1][0]=='(' && nonEmpty(_tc) && _tc[1][0]==')' && (_tc[1].length>1 && _tc[1][1] in set(['=','->']))) ? (self(_tc[1].slice(2),topLevel,__Escape)) : (_t2[1][0]=='(' && (isEmpty(_tc[1]) || _tc[1][0]!=')')) ? do_raise_syntax("expect symbol ')'") : (_t2[1][0]!='(' && nonEmpty(_tc[1]) && (_tc[1][0] in set(['=','->']))) ? self(_tc[1].slice(1),topLevel,__Escape) : do_raise_syntax("expect symbol '=' or '->', given: '"+(nonEmpty(_tc[1])&&_tc[1][0]?_tc[1][0]:'')+"'") ); })((!(nonEmpty(_t2[1]) && _t2[1][0]=='=')) ? ( (function(_ta){ return [_ta[0].length==1 && _ta[0][0]==null? []: _ta[0],_ta[1]]; })(wapper( function(self, rf, _ta){ return nonEmpty(_ta) ? ( (function(_tx){ return (nonEmpty(_tx[1]) && _tx[1][0]==',') ? (function(ty){return [[_tx[0]].concat(ty[0]),ty[1]]; })(self(rf,_tx[1].slice(1))):[[_tx[0]],_tx[1]]; })(rf(_ta,3,__Escape)) ) : (isEmpty(_ta) || _ta[0] in set(['->','=',')'])) ? [[],_ta] : do_raise_syntax("unexpect symbol '"+_ta[0]+"'"); })(self, _t2[1].slice(nonEmpty(_t2[1]) && _t2[1][0]=='(')) )) : [[], _t2[1]] ); }),_t.slice(1)) ) : do_raise_syntax("expect symbol ':', given: '"+_t[0]+"'"); })(__List.slice(1)) ) : self(__List, __Level-1, __Escape) ) : (__Level==2) ? ( (nonEmpty(__List) && (__List[0] in set(['delay','callcc','eval','curry']))) ? ( (function(_t,_f){ return (nonEmpty(_t) && _t[0] =='(') ? (function(_t0){ return (isEmpty(_t0[1]) || _t0[1][0]!=')') ? do_raise_syntax("expect symbol ')', given: '"+_t0[1][0]+"'") : [_t0[0],_t0[1].slice(1)]; } )(_f(_t.slice(1),true)) : _f(_t,false); })(__List.slice(1),function(_t,_mk){ return (function(_t0){ return [[__List[0],_t0[0]],_t0[1]]; })(self(_t, _mk?topLevel:3, __Escape)) })) : self(__List, __Level-1,__Escape) ) : (__Level==3) ? ( wapper( function(self, rf, _t){ return (nonEmpty(_t[1]) && _t[1][0]=='(') ? ( (function(_t0){ return self(rf, [['<-',_t[0],_t0[0]],_t0[1]]); })((function(_t){return [['()',(_t.length>2 || _t[0]!=null) ? _t.slice(0,-1) : []],_t[_t.length-1].slice(1)];})( wapper( function(self, rf, _t0){ return (_t0[1] && _t0[1][0]==',') ? (function(_tx){return [_t0[0]].concat(self(rf, _tx));})(rf(_t0[1].slice(1),topLevel,__Escape)) : _t0; })(rf, rf(_t[1].slice(1),topLevel,__Escape)) )) ) : (nonEmpty(_t[1]) && _t[1][0]=='{') ? do_raise_syntax("unexpect symbol '{'") : (nonEmpty(_t[1]) && !_t[1][0].toString().match(/(\-\>|\\(?:\(|\{)|(?:\)|\})\\|[<>=]{2}|[\>\<\=\,\+\-\*\/\%\(\)\^\!\|\:\{\}\[\]\_\n\~])/)) ? ( (function(_t0){ //return self(rf, [['*',_t[0],_t0[0]],_t0[1]]); do_raise_syntax("unexpect symbol '"+_t[1][0]+"'"); })(rf(_t[1], 4, __Escape)) ) : _t; })(self, self(__List, __Level-1, __Escape)) ) : (__Level==4) ? ( (nonEmpty(__List) && __List[0]=='|') ? ( (function(_t0){ return [['|',_t0.slice(0,-2)],_t0[_t0.length-1]]; })(wapper( function(self, rf, _t){ return (nonEmpty(_t) && _t[0]=='|') ? ( (function(_tx){ return (nonEmpty(_tx[1]) && _tx[1][0]==':') ? ( (function(_ty){ return [[_tx[0], _ty[0]]].concat(self(rf, _ty[1])); })(rf(_tx[1].slice(1),topLevel,__Escape)) ) : do_raise_syntax("expect symbol ':'"); })(rf(_t.slice(1),topLevel,__Escape)) ) : [[], _t]; })(self, __List)) ) : self(__List, __Level-1, __Escape) ) : (__Level>4 && __Level<12) ? ( wapper( function(self, rf, _t){ return (_t[1] && _t[1][0] in [set(['->']),set(['_']),set(['!']),set(['^']),set(['*','/','%']),set(['+','-']),set(['=','!=','<','>','<=','>='])][__Level-5]) ? ( (function(x){ return (function(_t0){ return x ? ((nonEmpty(_t0[1]) && _t0[1][0]=='}') ? self(rf, [[_t[1][0],_t[0],_t0[0]],_t0[1].slice(1)]) : do_raise_syntax("expect symbol '}'")) : self(rf, [[_t[1][0],_t[0],_t0[0]],_t0[1]]); })(rf(_t[1].slice(1+x), x?11:__Level-1, __Escape)); })(((__Level==6 || __Level==8) && _t[1].length>1 && _t[1][1]=='{')) ) : _t; })(self, self(__List, __Level-1, __Escape)) ) : (self(__List, __Level-1, __Escape) ); }); var parser=wapper( function(self, __List){ return ((function(rf, _t){ return (isEmpty(_t[1])||_t[1][0]=='\n') ? [_t[0]].concat((nonEmpty(_t[1])) ? rf(_t[1].slice(1)) : []) : do_raise_syntax("Unexpected end of line"); } )(self, parser_unit(__List))); }); var merge_dict=function(x,y){ return extend(x,y); } var builtin_func_signature=function(f){ var signature={ 'apply': ['lambda','apply',['f','x']], 'isFunction': ['lambda','isFunction',['x']], 'isList': ['lambda','isList',['x']], 'isNumber': ['lambda','isNumber',['x']], 'isNone': ['lambda','isNone',['x']], 'isAst': ['lambda','isAst',['x']], 'int': ['lambda','int',['x']], 'float': ['lambda','float',['x']], 'len': ['lambda','len',['x']], 'map': ['lambda','map',['f','x']], 'filter': ['lambda','filter',['f','x']], 'reduce': ['lambda','reduce',['f','x']], 'ceil': ['lambda','ceil',['x']], 'floor': ['lambda','floor',['x']], 'boolean': ['lambda','boolean',['x']], 'abs': ['lambda','abs',['x']], 'sin': ['lambda','sin',['x']], 'cos': ['lambda','cos',['x']], 'tan': ['lambda','tan',['x']], 'ln': ['lambda','ln',['x']], 'exp': ['lambda','exp',['x']], 'pi': ['lambda','pi',[]], 'e': ['lambda','e',[]], 'random': ['lambda','random',[]], 'and': ['lambda','and',['x','y']], 'or': ['lambda','or',['x','y']], 'not': ['lambda','or',['x']], 'input': ['lambda','input',[]], 'output': ['lambda','output',['x']], 'suspend': ['lambda','suspend',['f']], 'clear': ['lambda','suspend',[]], 'halt': ['lambda','halt',[]], }; return signature[f]; }; var global_symtable=function(_t){ var numeric_func=function(f,name){ return function(x,cont){ if(!isNaN(x)){ return cont.bind(null,f(x)); } else{ do_raise("call lambda <"+name+"> with not isnumeric argument"); } } } var builtin=function(f,name,args,decay){ if(decay === undefined) { decay = true; } return val_func(builtin_func(f,name,args,decay)); } var builtin_func_list={ 'apply': builtin(function(f,x,cont){ if(isFunction(f)&&f(2)!='Ast'&&f(2)!='free_identifier'){ if(isArray(x)){ return f().bind(null,x,cont); } else{ return f().bind(null,[val_func(x)],cont); } } else{ return result_of.bind(null, val_func(f), function(v){ do_raise("calling a not callable object "+v); }); } },'apply',['f','x']), 'isFunction': builtin(function(x,cont){ if(isFunction(x)&&x(2)!='Ast'&&x(2)!='free_identifier'){ return cont.bind(null,true); } else{ return cont.bind(null,false); } },'isFunction',['x']), 'isList': builtin(function(x,cont){ if(isArray(x)){ return cont.bind(null,true); } else{ return cont.bind(null,false); } },'isList',['x']), 'isNumber': builtin(function(x,cont){ if(isNumber(x)){ return cont.bind(null,true); } else{ return cont.bind(null,false); } },'isNumber',['x']), 'isNone': builtin(function(x,cont){ if(x==null){ return cont.bind(null,true); } else{ return cont.bind(null,false); } },'isNone',['x']), 'isAst': builtin(function(x,cont){ if(isFunction(x)&&x(2)=='Ast'){ return cont.bind(null,true); } else{ return cont.bind(null,false); } },'isAst',['x']), 'int': builtin(numeric_func(function(x){return Math.floor(x);},'int'),'int',['x']), 'float': builtin(numeric_func(function(x){return x;},'float'),'float',['x']), 'boolean': builtin(function(x,cont){return cont.bind(null,toBoolean(x));},'boolean',['x']), 'len': builtin(function(x,cont){ if(isArray(x)){ return cont.bind(null,x.length); } else{ do_raise("call lambda <len> with not vector argument"); } },'len',['x']), 'map': builtin(function(f,x,cont){ if(isArray(x)){ return map_cps.bind(null,function(y,cont){ return f().bind(null,[y],cont); }, x,cont); } else{ do_raise("call lambda <map> with not vector argument"); } },'map',['f','x']), 'filter': builtin(function(f,x,cont){ if(isArray(x)){ return filter_cps.bind(null,function(y,cont){ return f().bind(null,[y],function(v){ return v().bind(null,null,function(cond){ return cont.bind(null,Boolean(cond) && !(isArray(cond) && isEmpty(cond))); }); }); }, x,cont); } else{ do_raise("call lambda <filter> with not vector argument"); } },'filter',['f','x']), 'reduce': builtin(function(f,x,cont){ if(isArray(x)){ if(nonEmpty(x)){ return reduce_cps.bind(null,function(a,b,cont){ return f().bind(null,[a,b],cont); }, x,cont); } else{ return cont.bind(null,[]); } } else{ do_raise("call lambda <reduce> with not vector argument"); } },'reduce',['f','x']), 'ceil': builtin(numeric_func(function(x){return Math.ceil(x);},'ceil'),['x']), 'floor': builtin(numeric_func(function(x){return Math.floor(x);},'floor'),'floor',['x']), 'abs': builtin(numeric_func(function(x){return Math.abs(x);},'abs'),'abs',['x']), 'sin': builtin(numeric_func(function(x){return Math.sin(x);},'sin'),'sin',['x']), 'cos': builtin(numeric_func(function(x){return Math.cos(x);},'cos'),'cos',['x']), 'tan': builtin(numeric_func(function(x){return Math.tan(x);},'tan'),'tan',['x']), 'ln': builtin(numeric_func(function(x){return Math.log(x);},'ln'),'ln',['x']), 'exp': builtin(numeric_func(function(x){return Math.exp(x);},'exp'),'exp',['x']), 'pi': builtin(function(cont){return cont.bind(null,Math.PI);},'pi',[]), 'e': builtin(function(cont){return cont.bind(null,Math.E);},'e',[]), 'random': builtin(function(cont){return cont.bind(null,Math.random());},'random',[]), 'and': builtin(function(x,y,cont){ return x().bind(null,null,function(a){ return !toBoolean(a)? cont.bind(null,val_func(false)) : y().bind(null,null,function(b){ return !toBoolean(b)? cont.bind(null,val_func(false)) : cont.bind(null,val_func(true)); }); }); },'and',['x','y'],false), 'or': builtin(function(x,y,cont){ return x().bind(null,null,function(a){ return toBoolean(a)? cont.bind(null,val_func(true)) : y().bind(null,null,function(b){ return toBoolean(b)? cont.bind(null,val_func(true)) : cont.bind(null,val_func(false)); }); }); },'or',['x','y'],false), 'not': builtin(function(x,cont){return cont(!toBoolean(x));},'or',['x']), 'input': builtin(function(cont){ console_read(function(code){ trampoline_exec(evaluate(parser(lexer(code))[0],{},{},function(x){ trampoline_exec(x().bind(null,null,cont)); })); }); },'input',[]), 'output': builtin(function(x,cont){ return result_of.bind(null, x, function(v){ console_write(v); console_sleep(function(){ trampoline_exec(cont.bind(null,x)); }, 10); }); },'output',['x'], false), 'suspend': builtin(function(x,cont){ console_suspend(function(){ trampoline_exec(cont.bind(null,x)); }); },'suspend',['f'], false), 'clear': builtin(function(cont){ console_clear(); return cont(null); },'clear',[]), 'halt': builtin(function(cont){ return null; },'halt',[], false), }; var ret={}; _t.forEach(function(item,index){ if(isArray(item) && nonEmpty(item) && item[0]=='lambda'){ if(!(item[1] in ret)){ ret[item[1]]=[item[0],item[1],[],[]]; } ret[item[1]][2].push(item[2]); ret[item[1]][3].push(item[3]); if(ret[item[1]][2][0].length!=item[2].length){ do_raise_syntax("define lambda<"+(item[1] ? item[1] : 'unnamed')+"> with unmatched arguments,\n given:"+ '('+ret[item[1]][2][0].map(function(x){ return AstToString(x).replace(/\n$/,''); }).join(',')+') and '+ '('+item[2].map(function(x){ return AstToString(x).replace(/\n$/,''); }).join(',')+')'); } } }); for (var key in ret) { ret[key]=val_func(func(ret[key][0],ret[key][1],ret[key][2],ret[key][3], {}, ret, evaluate)); } merge_dict(ret, builtin_func_list); merge_dict(ret, {'true':val_func(true),'false':val_func(false)}); return ret; } var macro_symtable=function(_t,_gsym){ if(_gsym === undefined) { _gsym = {}; } var ret={}, temp={}; _t.forEach(function(item,index){ if(isArray(item) && nonEmpty(item) && item[0] in set(['def','def_const','def!','def!_const'])){ if(!(item[1] in temp)){ temp[item[1]]=[item[0],item[1],[],[]]; } temp[item[1]][2].push(item[2]); temp[item[1]][3].push(item[3]); if(temp[item[1]][2][0].length!=item[2].length){ do_raise_syntax("define macro<"+(item[1] ? item[1] : 'unnamed')+"> with unmatched arguments,\n given:"+ '('+temp[item[1]][2][0].map(function(x){ return AstToString(x).replace(/\n$/,''); }).join(',')+') and '+ '('+item[2].map(function(x){ return AstToString(x).replace(/\n$/,''); }).join(',')+')'); } } }); for (var key in temp) { temp[key]=val_func(func(temp[key][0],temp[key][1],temp[key][2],temp[key][3], {}, temp, evaluate, true)); ret[key]=temp[key]; } merge_dict(temp, _gsym); return ret; } var macro_expansion=function(Ast, cont){ var gsym=global_symtable(Ast); var msym=macro_symtable(Ast,gsym); var KFFD=(function(_t, _msym, cont){ var id_set={}; var rename_set={}; var S=function(index, _e){ return (function(_t){ if(nonEmpty(_t)){ if(!(_t in id_set)){ id_set[_t]={}; } id_set[_t][index]=true; if(_e){ return ['#', _t, index].concat(_e); } else{ return ['#', _t, index]; } } else{ return _t; } }); } var T=function(_t, s){ if(isArray(_t)){ if(nonEmpty(_t)){ if(_t[0] in set(['->','<-','!=','<=','>=','<','>','=','+','-','*','/','%','^','!','_'])){ return [_t[0], T(_t[1],s), T(_t[2],s)]; } else if(_t[0]=='()'){ return [_t[0],_t[1].map(function(x){ return T(x,s); })]; } else if(_t[0] in set(['[]','\\()\\','\\{}\\','~','delay','callcc','eval','curry'])){ return [_t[0], T(_t[1],s)]; } else if(_t[0]=='|'){ return [_t[0],_t[1].map(function(x){ return [T(x[0],s),T(x[1],s)]; })]; } else if(_t[0]=='None'){ return _t; } else if(_t[0]=='lambda'){ return [_t[0], T(_t[1],s), _t[2].map(function(x){ return T(x,s); }), T(_t[3],s)]; } else if(_t[0] in set(['def','def_const','def!','def!_const'])){ return null; } else if(_t[0]=='#'){ return _t; } } else{ return null; } } else{ if(isString(_t) && !(_t in _msym)){ return s(_t); } else{ return _t; } } } var E=function(_t, index, cont){ var E_impl=function(_t, index, env, bound, match, cont){ if(isArray(_t)){ if(nonEmpty(_t)){ if(_t[0] in set(['->','!=','<=','>=','<','>','=','+','-','*','/','%','^','!','_'])){ return E_impl.bind(null,_t[1], index, env, bound, 0, function(x){ return E_impl.bind(null,_t[2], index, env, bound, 0, function(y){ return cont.bind(null,[_t[0],x,y]); }); }); } else if(_t[0]=='<-'){ return E_impl.bind(null,_t[1], index, env, bound, match, function(x){ return E_impl.bind(null,_t[2], index, env, bound, match, function(y){ if(isString(x) && x in _msym){ var dirty=(_msym[x](-1)[0].indexOf('!')!=-1); return _msym[x]().bind(null,null,function(f){ return f().bind(null,y[1].map(function(k){ return val_func(ast_func(k)); }),function(v0){ return v0().bind(null,null, function(v){ if(!isFunction(v)) v=val_func(v); if(dirty){ return E_impl.bind(null, T(v(-1), function(_t){ return _t in bound? S(index-1)(_t):S(index-1,env)(_t); }), index, env, bound, match, function(n){ return cont.bind(null,n); }); } else{ return E_impl.bind(null, T(v(-1), S(index,v(-3))), index+1, v(-3), {}, match, function(n){ return cont.bind(null,n); }); } }); }); }); } return cont.bind(null,[_t[0],x,y]); }); }); } else if(_t[0]=='()'){ return map_cps.bind(null,function(x,cont){ return E_impl.bind(null,x, index, env, bound, match, cont); }, _t[1], function(x){ return cont.bind(null,['()',x]); }); } else if(_t[0] in set(['[]','\\()\\','\\{}\\','delay','callcc','eval','curry'])){ return E_impl.bind(null,_t[1], index, env, bound, match+(match&&(_t[0]=='[]'||(-(_t[0] in set(['\\()\\','\\{}\\']))))), function(x){ return cont.bind(null,[_t[0],x]); }); } else if(_t[0]=='~'){ return E_impl.bind(null,_t[1], index, env, bound, match, function(x){ if(isString(x) || x==null || (isArray(x)&&nonEmpty(x)&&x[0] in set(['#','\\()\\','\\{}\\']))){ if (isString(x) && nonEmpty(x)){ bound[x]=true; } else if(isArray(x) && x[0]=='#' && isString(x[1]) && nonEmpty(x[1])){ bound[x[1]]=true; } return cont.bind(null,[_t[0],x]); } else{ do_raise_syntax("expect identifier, given: "+AstToString(x).replace(/\n$/,'')); } }); } if(_t[0]=='->'){ return E_impl.bind(null,_t[1], index, env, bound, match, function(x){ if(nonEmpty(_t[2]) && _t[2][0]=='|'){ return E_impl.bind(null,_t[2], index, env, bound, 1, function(y){ return cont.bind(null,[_t[0],x,y]); }); } else{ return E_impl.bind(null,_t[2], index, env, bound, match, function(y){ return cont.bind(null,[_t[0],x,y]); }); } }); } else if(_t[0]=='|'){ return map_cps.bind(null,function(x,cont){ var sub=bound; if(match==1){ sub={}; for (var key in bound) { sub[key]=bound[key]; } } return E_impl.bind(null, x[0], index, env, sub, match, function(y){ return E_impl.bind(null, x[1], index, env, sub, 0, function(z){ return cont.bind(null,[y,z]); }); }); }, _t[1], function(x){ return cont.bind(null,['|',x]); }); } else if(_t[0]=='None'){ return cont.bind(null,_t); } else if(_t[0]=='lambda'){ var b={}; return E_impl.bind(null,_t[1], index, env, bound, match, function(x){ if(!(x==null || isString(x) || (isArray(x)&&nonEmpty(x)&&x[0] in set(['#','~','\\{}\\','\\()\\'])))){ do_raise_syntax("invaild function name: "+AstToString(x).replace(/\n$/,'')); } return E_impl.bind(null,['()',_t[2]], index, env, b, 1, function(y){ y[1].forEach(function(item,index){ if(isString(item) && nonEmpty(item)){ b[item]=true; } else if(isArray(item)&&nonEmpty(item)&&item[0]=='#'){ b[item[1]]=true; } else if(!(isArray(item)&&nonEmpty(item)&&item[0] in set (['#','~','lambda','[]','()','\\{}\\','\\()\\']) || isNumber(item) || item==null)){ do_raise_syntax("invaild function argument: "+AstToString(item).replace(/\n$/,'')); } }); return E_impl.bind(null,_t[3], index, env, b, match, function(z){ return cont.bind(null,[_t[0],x==null?'':x,y[1],z]); }); }); }); } else if(_t[0] in set(['def','def_const','def!','def!_const'])){ return cont.bind(null,null); } else if(_t[0]=='#'){ return cont.bind(null,_t); } } else{ return cont.bind(null,null); } } else{ if(isString(_t) && _t in _msym && _msym[_t](-1)[0] in set(['def_const','def!_const'])){ var dirty=(_msym[_t](-1)[0].indexOf('!')!=-1); return _msym[_t]().bind(null,null,function(f){ return f().bind(null,[],function(v0){ return v0().bind(null,null, function(v){ if(!isFunction(v)) v=val_func(v); if(dirty){ return E_impl.bind(null, T(v(-1), function(_t){ return _t in bound? S(index-1)(_t) : S(index-1,env)(_t); }), index, env, bound, match, function(n){ return cont.bind(null,n); }); } else{ return E_impl.bind(null, T(v(-1), S(index,v(-3))), index+1, v(-3), {}, match, function(n){ return cont.bind(null,n); }); } }); }); }); } else{ return cont.bind(null,_t); } } } return E_impl.bind(null,_t,index,undefined,{},0,cont); } var A=function(_t){ if(isArray(_t)){ if(nonEmpty(_t)){ if(_t[0] in set(['->','<-','!=','<=','>=','<','>','=','+','-','*','/','%','^','!','_'])){ return [_t[0], A(_t[1]), A(_t[2])]; } else if(_t[0]=='()'){ return [_t[0],_t[1].map(function(x){ return A(x); })]; } else if(_t[0] in set(['[]','\\()\\','\\{}\\','delay','callcc','eval','curry'])){ return [_t[0], A(_t[1])]; } else if(_t[0]=='~'){ if(isArray(_t[1]) && nonEmpty(_t[1]) && _t[1][0]=='#'){ if(Object.keys(id_set[_t[1][1]]).length>1){ var name=_t[1][1]; var i=0; while(name+'_'+i in id_set) ++i; name=name+'_'+i; id_set[name]={}; id_set[name][_t[1][2]]=true; rename_set[_t[1][1]+'#'+_t[1][2]]=name; } else{ rename_set[_t[1][1]+'#'+_t[1][2]]=_t[1][1]; } } return [_t[0], A(_t[1])]; } else if(_t[0]=='|'){ return [_t[0],_t[1].map(function(x){ return [A(x[0]),A(x[1])]; })]; } else if(_t[0]=='None'){ return ['None']; } else if(_t[0]=='lambda'){ var args=_t[2] .map(function(x){ return A(x); }) .map(function(x){ if(isArray(x) && x[0]=='#'){ if(Object.keys(id_set[x[1]]).length>1){ var name=x[1]; var i=0; while(name+'_'+i in id_set) ++i; name=name+'_'+i; id_set[name]={}; id_set[name][x[2]]=true; rename_set[x[1]+'#'+x[2]]=name; return name; } else{ rename_set[x[1]+'#'+x[2]]=x[1]; return x[1]; } } else{ return x; } }); return [_t[0], A(_t[1]), args, A(_t[3])]; } else if(_t[0] in set(['def','def_const','def!','def!_const'])){ return null; } else if(_t[0]=='#'){ if(_t[2]==0){ return _t[1]; } else{ return ((_t[1]+'#'+_t[2]) in rename_set ? rename_set[(_t[1]+'#'+_t[2])] : _t); } } } else{ return null; } } else{ return _t; } } var U=function(_t){ if(isArray(_t)){ if(nonEmpty(_t)){ if(_t[0] in set(['->','<-','!=','<=','>=','<','>','=','+','-','*','/','%','^','!','_'])){ return [_t[0], U(_t[1]), U(_t[2])]; } else if(_t[0]=='()'){ return [_t[0],_t[1].map(function(x){ return U(x); })]; } else if(_t[0] in set(['[]','\\()\\','\\{}\\','~','delay','callcc','eval','curry'])){ return [_t[0], U(_t[1])]; } else if(_t[0]=='|'){ return [_t[0],_t[1].map(function(x){ return [U(x[0]),U(x[1])]; })]; } else if(_t[0]=='None'){ return ['None']; } else if(_t[0]=='lambda'){ var f=_t[1]==null ? '' : isArray(_t[1]) && nonEmpty(_t[1]) && _t[1][0]=='#' ? _t[1][1] : _t[1]; return [_t[0], f, _t[2].map(function(x){ return U(x); }), U(_t[3])]; } else if(_t[0] in set(['def','def_const','def!','def!_const'])){ return null; } else if(_t[0]=='#'){ if(_t.length==3){ return _t[1]; } else{ return _t; } } } else{ return null; } } else{ return _t; } } return E.bind(null,T(_t,S(0)),1,function(x){ return cont.bind(null, U(A(x))); }); }); var expansion=(function(_t, _msym, cont){ return map_cps.bind(null,function(x,cont){ return KFFD.bind(null, x, _msym, cont); }, _t, function(x){ return cont.bind(null,x.filter(function(v){ return (isArray(v) && nonEmpty(v)) || v!=null; })); }); }); return (expansion.bind(null, Ast, msym, function(x){ return cont.bind(null,x); })); } var environment=function(_env, _symtable){ return function(_syb){ return (_syb in _env) ? _env[_syb] : (_syb in _symtable) ? _symtable[_syb] : do_raise("undefine symbol: "+_syb); }; } var ast_func=function(_ast, _env, _gsym){ var code=AstToString(_ast).replace(/\n$/,''); if(code.indexOf('\n')==-1){ code='['+code+']'; } else{ code='[\n'+indent(code)+'\n]'; } return function(i){ if(i === undefined) { i = 0; } switch(i){ case -3: return [_env, _gsym]; case -1: return _ast; case 0: do_raise("invaild evaluate on Ast: "+code); case 1: return function(){ return code; } case 2: return 'Ast'; } } } var builtin_func=function(f, name, args, decay){ if(decay === undefined) { decay = true; } return function(i){ if(i === undefined) { i = 0; } switch(i){ case -2: return args.length; case -1: return name; case 0: return function(_args, cont){ if(_args.length==args.length){ if(!decay){ return f.bind.apply(f, [null].concat(_args).concat([function(x){ return cont.bind(null,x); }])); } else{ return map_cps.bind(null, function(x,cont){ return x().bind(null,null,cont); }, _args, function(x){ return f.bind.apply(f, [null].concat(x).concat([function(y){ return cont.bind(null,val_func(y)); }])); }); } } else{ do_raise("call lambda<"+name+"> with unmatched arguments,\nexpect: "+argument_number(args.length)+" ("+ args.join(',')+'),\ngiven: '+ argument_number(_args.length) ); } }; case 1: return function(cont){ return cont.bind(null, ('lambda<'+name+'('+args.join(', ')+')>')); } case 2: return 'lambda_builtin'; } } } var continuation_func=function(cont){ return function(i){ if(i === undefined) { i = 0; } switch(i){ case -2: return 1; case -1: do_raise("No explicit Ast of continuation function"); case 0: return function(_args, _cont){ if(_args.length==1){ return cont.bind(null, _args[0]); } else{ do_raise('call lambda<<continuation>> with unmatched arguments,\nexpect: 1 argument (return_value),\ngiven: '+ argument_number(_args.length) ); } }; case 1: return function(cont){ return cont.bind('lambda<<continuation>>'); } case 2: return 'lambda_continuation'; } } } var func=function(_type, _name, _args, _body, _env, _gsym, _eval, _macro){ var decay=_args.length==1 && Object.keys(set(_args[0].filter(isString))).length==_args[0].length; if(_macro === undefined) { _macro = false; } return function(i){ if(i === undefined) { i = 0; } switch(i){ case -2: return _args[0].length; case -1: return (function(){ if(_args.length==1){ return [_type,_name,_args[0],_body[0]]; } else{ var atom=_args[0].length==1; var args=[], body=[]; for(var i in _args[0]) args.push('arg_'+i); for(var i in _args) body.push([atom?(function(x){ return isString(x)? ['~',x]:x; })(_args[i][0]):['()',_args[i].map(function(x){ return isString(x)? ['~',x]:x; })],_body[i]]); body=['->',atom?args[0]:['()',args],['|',body]]; return [_type,_name,args,body]; } })(); case 0: return function(_args0, cont){ var atom=_args[0].length==1; var err = function(){ if(_args.length==1){ do_raise("call "+(_macro?"macro":"lambda")+"<"+((_name) ? _name : 'unnamed')+"> with unmatched arguments,\nexpect: "+ argument_number(_args.length) +"("+ _args[0].map(function(x){ return AstToString(x).replace(/\n$/,''); }).join(',')+'),\ngiven: '+ argument_number(_args0.length) ); } else{ do_raise("call "+(_macro?"macro":"lambda")+"<"+((_name) ? _name : 'unnamed')+"> with unmatched arguments,\nexpect one of: "+ _args.map(function(x){return '('+x.map(function(y){ return AstToString(y).replace(/\n$/,''); }).join(',')+')'; }).join(', ') ); } } var L = function(i,cont){ return _eval.bind(null, atom?(function(x){ return isString(x)? ['~',x,-1]:x; })(_args[i][0]):['()',_args[i].map(function(x){ return isString(x)? ['~',x,-1]:x; })], _env, _gsym, function(args){ return unify.bind(null,atom?_args0[0]:val_func(_args0),args,function(u){ if(u[0]){ return _eval.bind(null, _body[i], merge_dict(u[1], _env), _gsym, cont); } else if(i+1<_args.length){ return L.bind(null,i+1,cont); } else{ err(); } }); }); } if(_args0.length==_args[0].length){ if(decay){ var _new_env={}; _args[0].forEach(function(item,index){ _new_env[item]=_args0[index]; }); var ret; return _eval.bind(null, _body[0], merge_dict(_new_env, _env), _gsym, cont); } else{ return L.bind(null,0,cont); } } else{ err(); } }; case 1: return function(cont){ if(_args.length==1){ return cont.bind(null, ((_macro?"macro":"lambda")+'<'+ (nonEmpty(_name) ? _name : 'unnamed')+ '('+_args[0].map(function(x){ return AstToString(x).replace(/\n$/,''); }).join(', ')+')>')); } else{ var args=[]; for(var i in _args[0]) args.push('arg_'+i); return cont.bind(null, ((_macro?"macro":"lambda")+'<'+(nonEmpty(_name) ? _name : 'unnamed')+'('+args.join(', ')+')>')); } } case 2: return (_macro?"macro":"lambda"); } } } var delay_func=function(_body, _env, _gsym, _eval, value){ return function(i){ if(i === undefined) { i = 0; } if(i==-1){ return _body; } else if(i==-2){ return (isArray(_body) && nonEmpty(_body) && _body[0]=='lambda') ? _body[2].length : undefined; } else if(i==3){ return 'delay_expr'; } else{ if(typeof(value) == 'undefined'){ return function(){ var args=Array.prototype.slice.call(arguments); return _eval.bind(null, _body, _env, _gsym, function(x){ value=x; var r=x(i); return r.bind.apply(r,[null].concat(Array.prototype.slice.call(args))); }); } } else{ return value(i); } } } } var val_func=function(_val){ return function(i){ if(i === undefined) { i = 0; } switch(i){ case -1: return (wapper(function(self,_v){ if(isFunction(_v)){ return _v(-1); } else if(isArray(_v)){ return ['()',_v.map(function(x){ return self(x); })]; } else if(_v==null){ return 'None'; } return _v; })(_val)); case 0: return function(_args, cont){ return cont.bind(null,_val); }; case 1: return function(cont){ if(isFunction(_val)){ return _val(1).bind(null, cont); } else if(isArray(_val)){ return map_cps.bind(null, result_of, _val, function(v){ return cont.bind(null, '('+v.toString()+')'); }); } else if(_val==null){ return cont.bind(null, 'None'); } return cont.bind(null, _val.toString()); } case 2: return 'value'; } } } var free_identifier_func=function(id){ return function(i){ if(i === undefined) { i = 0; } switch(i){ case -1: return ['~',id,1]; case 0: return function(_args, cont){ return cont.bind(null,null); }; case 1: return (function(cont){ return cont.bind(null, 'None'); }); case 2: return 'free_identifier'; case 3: return id; } } } var func_combinator=function(x, y, op, op_ch){ var getFunc=function(v){ if(v(2)=='lambda_continuation'){ return ['lambda','continuation',['retValue']]; } if(v(2)=='lambda_builtin'){ return builtin_func_signature(v(-1)); } else{ return v(-1); } }; var fx=getFunc(x); var fy=getFunc(y); var args_length=0; if(x(2)!='value'&&y(2)!='value'){ if(fx[2].length!=fy[2].length){ do_raise("combine lambda<"+((fx[1]) ? fx[1] : 'unnamed')+"> with lambda<"+((fy[1]) ? fy[1] : 'unnamed')+"> unmatched arguments,\n arguments of "+ "lambda<"+((fx[1]) ? fx[1] : 'unnamed')+">: ("+fx[2].join(',')+"),\n arguments of "+ "lambda<"+((fy[1]) ? fy[1] : 'unnamed')+">: ("+fy[2].join(',')+")" ); } args_length=fx[2].length; } return function(i){ if(i === undefined) { i = 0; } switch(i){ case -2: return args_length; case -1: return (function(){ var n,m=0; var args=[]; var fx_name='',fy_name=''; var call_x,call_y; if(x(2)!='value'){ n=fx[2].length; fx_name=fx[1]; } if(y(2)!='value'){ n=fy[2].length; fy_name=fy[1]; } for (var i = 0; i<n; i++) { while(('arg_'+m)==fx_name||('arg_'+m)==fy_name){ m++; } args.push('arg_'+m); m++; } if(x(2)!='value') call_x=['<-',x(-1),['()',args]]; else call_x=x(-1); if(y(2)!='value') call_y=['<-',y(-1),['()',args]]; else call_y=y(-1); return ['lambda','',args,[op_ch,call_x,call_y]]; })(); case 0: return function(_args, cont){ return x().bind(null,_args, function(x){ return y().bind(null,_args, function(y){ return op.bind(null,x,y,cont); }); }); }; case 1: return function(cont){ return result_of.bind(null, x, function(v1){ result_of.bind(null, y, function(v2){ return cont.bind(null, 'lambda<'+v1+op_ch+v2+'>'); }); }); } case 2: return 'lambda_combinator'; } } } var curry_func=function(f){ if(!isFunction(f) || f(2)=='Ast' || f(2)=='free_identifier'){ do_raise("currying a not callable object "); } else if(f(2)=='lambda_continuation'){ return f; } else if(f(-2)==1){ return f; } var args_length=f(-2); return wapper(function(self,i,args,index){ if(args === undefined) { args = []; } if(index === undefined) { index = 0; } if(i === undefined) { i = 0; } switch(i){ case -2: return 1; case -1: return ((function(){ var L=function(i){ if(i+1<args_length){ return ['lambda','',['arg_'+i],L(i+1)]; } else{ var _args=[]; for (var _i = index; _i < args_length; ++_i) { _args.push('arg_'+i); } return ['lambda','',['arg_'+i],['<-',f(-1),['()',args.map(function(x){ return x(-1); }).concat(_args)]]]; } } return L(index); })()); case 0: return function(_args, cont){ if(_args.length==1 && index+1<args_length){ return cont.bind(null, val_func(function(i){ return self(i,args.concat([_args[0]]),index+1); })); } else if(_args.length==1 && index+1==args_length){ return f().bind(null,args.concat([_args[0]]),cont); } else{ do_raise('call currying '+f(1)()+' with unmatched arguments,\n expect: 1 argument (arg_'+index+'), given: '+ argument_number(_args.length) ); } }; case 1: return (function(cont){ return f(1).bind(null, function(v){return cont.bind(null, 'currying '+v);}); }); case 2: return 'lambda_curry'; } }); } var op_args=function(f){ return function(x){ if(isFunction(x)&&x(2)=='free_identifier') return f.bind(null,null); else if(isFunction(x)&&x(2)=='Ast') do_raise("invaild evaluate on Ast: "+x(1)()); else return f.bind(null,x); } } var op_gen=function(op, op_ch){ return wapper(function(self,x,y,cont){ return x().bind(null,null,op_args(function(a){ return y().bind(null,null,op_args(function(b){ if(!isFunction(a)&&!isFunction(b)){ return op.bind(null,a,b,function(x){ return cont.bind(null,val_func(x)); }); } else{ return cont.bind(null,val_func(func_combinator((isFunction(a)?a:val_func(x)),(isFunction(b)?b:val_func(y)),self,op_ch))); } })); })); }); } var op_check=function(f){ return function(x,y,cont){ if(!isArray(x)&&!isArray(y)){ return f.bind(null,x,y,cont); } else{ do_raise("invaild operatation on vector"); } }; } var combinator=function(_sym){ return { '<-':function(x,y,cont){ return x().bind(null,null,function(f){ if(isFunction(f) && f(2)!='value'){ return y().bind(null,null,function(_args){ return f().bind(null,_args,cont); }); } else{ return result_of.bind(null, x, function(v){ do_raise("calling a not callable object "+v); }); } }); }, '<=':op_gen(op_check(function(a,b,cont){return cont.bind(null,a<=b);}),'<='), '>=':op_gen(op_check(function(a,b,cont){return cont.bind(null,a>=b);}),'>='), '<':op_gen(op_check(function(a,b,cont){return cont.bind(null,a<b);}),'<'), '>':op_gen(op_check(function(a,b,cont){return cont.bind(null,a>b);}),'>'), '!=':op_gen(op_check(function(a,b,cont){return cont.bind(null,a!=b);}),'!='), '=':op_gen(op_check(function(a,b,cont){return cont.bind(null,a==b);}),'='), '+':op_gen(function(a,b,cont){ if(!isArray(a)&&!isArray(b)){ return cont.bind(null,a+b); } else{ var x=isArray(a) ? a : [val_func(a)]; var y=isArray(b) ? b : [val_func(b)]; return cont.bind(null,x.concat(y)); } },'+'), '-':op_gen(function(a,b,cont){ if(!isArray(a)&&!isArray(b)){ return cont.bind(null,a-b); } else if(isArray(a)&&!isArray(b)){ return cont.bind(null,a.slice(0,-1)); } else if(!isArray(a)&&isArray(b)){ return cont.bind(null,b.slice(1)); } else if(isArray(a)&&isArray(b)){ if(a.length<=b.length){ return cont.bind(null,[]); } else{ return cont.bind(null,a.slice(0,-b.length)); } } },'-'), '*':op_gen(op_check(function(a,b,cont){return cont.bind(null,a*b);}),'*'), '/':op_gen(op_check(function(a,b,cont){return cont.bind(null,a/b);}),'/'), '%':op_gen(op_check(function(a,b,cont){return cont.bind(null,a%b);}),'%'), '^':op_gen(op_check(function(a,b,cont){return cont.bind(null,Math.pow(a,b));}),'^'), '_':op_gen(function(a,b,cont){ if(isArray(a)&&!isArray(b)){ if(Number.isInteger(b)){ if(b<=a.length&&b>0){ return a[b-1]().bind(null,null,function(r){ return cont.bind(null,r); }); } else{ do_raise("index of vector out of range"); } } else{ do_raise("invaild index of vector"); } } else{ do_raise("invaild operatation on vector"); } },'_'), '!':op_gen(op_check(function(a,b,cont){ var i=(b==null)?0:b; if(b<0){ return cont.bind(null,0); } else{ var ret=1; var x=a; while(x>b){ ret*=x--; } return cont.bind(null,ret); } }),'!'), }[_sym]; } var unify=function(n,m,cont){ var valE={}; var equivalent_value=function(val,cont,fail){ var visited_flag={}; var ev_impl=function(v,cont){ if(isFunction(v) && v(2)=='free_identifier'){ v=v(3); } if(v in visited_flag){ return fail; } visited_flag[v]=true; var x=v; while(x in valE){ x=valE[x]; } if(isArray(x) && nonEmpty(x) && x[0]=='Ast'){ delete visited_flag[v]; return cont.bind(null,ast_func(x[1])); } else if(isArray(x)){ return map_cps.bind(null,function(x0,cont){ return x0().bind(null,null,function(x1){ return ev_impl.bind(null,x1,function(x2){ return cont.bind(null,val_func(x2)); }); }); }, x, function(x){ delete visited_flag[v]; return cont.bind(null,x); }); } else if(isString(x)){ delete visited_flag[v]; valE[x]=null; return cont.bind(null,null); } else{ delete visited_flag[v]; return cont.bind(null,x); } } return ev_impl.bind(null,val,cont); } var unify_impl=function(_n,_m,cont){ var Alpha=function(x,y,u){ if(u === undefined) { u = false; } var alpha_impl=function(x,y,rename,last_rename,match){ if(u){ var ex=x,ey=y; if(isArray(x) && x.length==3 && x[0]=='~' && x[2]>0){ ex=isString(x[1])?'~'+x[1]:'~'; while(ex in valE) ex=valE[x]; } if(isArray(y) && y.length==3 && y[0]=='~' && y[2]>0){ ey=isString(y[1])?'~'+y[1]:'~'; while(ey in valE) ey=valE[y]; } if(ex=='~' || ey=='~' || (isString(ex) && nonEmpty(ex) && ex[0]=='~' && ex==ey)){ return true; } else if(isString(ex) && nonEmpty(ex) && ex[0]=='~'){ if(isString(ey) && nonEmpty(ey) && ey[0]=='~'){ valE[ex]=ey; } else{ valE[ex]=ast_func(ey); } return true; } else if(isString(ey) && nonEmpty(ey) && ey[0]=='~'){ valE[ey]=ast_func(ex); return true; } else if(isArray(ex) && nonEmpty(ex) && ex[0]=='Ast'){ ex=ex[1]; } else if(isArray(ey) && nonEmpty(ey) && ey[0]=='Ast'){ ey=ey[1]; } x=ex; y=ey; } if(isArray(x) && isArray(y)){ if(nonEmpty(x) && nonEmpty(y) && x[0]==y[0]){ if(x[0] in set(['<-','!=','<=','>=','<','>','=','+','-','*','/','^','!','_'])){ return alpha_impl(x[1],y[1],rename,last_rename,false) && alpha_impl(x[2],y[2],rename,last_rename,false); } else if(x[0]=='()'){ if(x[1].length==y[1].length){ for(var i in x[1]){ if(!alpha_impl(x[1][i],y[1][i],rename,last_rename,match)) return false; } return true; } else if(u && x[1].length==y[1].length+1 && x[1][x[1].length-1][0]=='~' && x[1][x[1].length-1][2]==2){ if(alpha_impl(x[1][x[1].length-1],['()',[]],rename,last_rename,match)){ for(var i in y[1]){ if(!alpha_impl(x[1][i],y[1][i],rename,last_rename,match)) return false; } return true; } else{ return false; } } else if(u && y[1].length==x[1].length+1 && y[1][y[1].length-1][0]=='~' && y[1][y[1].length-1][2]==2){ if(alpha_impl(['()',[]],y[1][y[1].length-1],rename,last_rename,match)){ for(var i in x[1]){ if(!alpha_impl(x[1][i],y[1][i],rename,last_rename,match)) return false; } return true; } else{ return false; } } else if(u && nonEmpty(y[1]) && x[1].length>y[1].length){ var last=y[1][y[1].length-1]; if(isArray(last) && nonEmpty(last) && last[0]=='~' && last[2]==2 && alpha_impl(['()',x[1].slice(y[1].length-1,x[1].length)],last,rename,last_rename,match)){ for(var i=0; i<y[1].length-1; ++i){ if(!alpha_impl(x[1][i],y[1][i],rename,last_rename,match)) return false; } return true; } else{ return false; } } else if(u && nonEmpty(x[1]) && x[1].length<y[1].length){ var last=x[1][x[1].length-1]; if(isArray(last) && nonEmpty(last) && last[0]=='~' && last[2]==2 && alpha_impl(last,['()',y[1].slice(x[1].length-1,y[1].length)],rename,last_rename,match)){ for(var i=0; i<x[1].length-1; ++i){ if(!alpha_impl(x[1][i],y[1][i],rename,last_rename,match)) return false; } return true; } else{ return false; } } else{ return false; } } else if(x[0] in set(['#','\\()\\','\\{}\\','delay','callcc','eval','curry'])){ return alpha_impl(x[1],y[1],rename,last_rename,match); } else if(x[0]=='[]'){ return alpha_impl(x[1],y[1],[{},{}],rename,match); } else if(x[0] in set(['\\()\\','\\{}\\'])){ return alpha_impl(x[1],y[1],last_rename,[{},{}],match); } else if(x[0]=='->'){ if(isArray(x[2]) && isArray(y[2])){ if(nonEmpty(x[2]) && nonEmpty(y[2]) && x[2][0]==y[2][0] && x[2][0]=='|'){ return alpha_impl(x[1],y[1],rename,last_rename,match) && alpha_impl(x[2],y[2],rename,last_rename,true); } } return alpha_impl(x[1],y[1],rename,last_rename,match) && alpha_impl(x[2],y[2],rename,last_rename,match); } else if(x[0]=='~'){ if(match){ if(x[1]==y[1]){ return true; } else if(x[1]!=y[1] && !(x[1] in rename[0]) && !(y[1] in rename[1])){ rename[0][y[1]]=x[1]; rename[1][x[1]]=y[1]; return true; } else{ return false; } } else{ return alpha_impl(x[1],y[1],rename,last_rename,match); } } else if(x[0]=='|'){ if(x[1].length==y[1].length){ for(var i in x[1]){ if(match){ var n=[{},{}]; for (var key in rename[0]) { n[0][key]=rename[0][key]; } for (var key in rename[1]) { n[1][key]=rename[1][key]; } if(!(alpha_impl(x[1][i][0],y[1][i][0],n,last_rename,match)&&alpha_impl(x[1][i][1],y[1][i][1],n,last_rename,false))) return false; } else{ if(!(alpha_impl(x[1][i][0],y[1][i][0],rename,last_rename,match)&&alpha_impl(x[1][i][1],y[1][i][1],rename,last_rename,false))) return false; } } return true; } else{ return false; } } else if(x[0]=='None'){ return true; } else if(x[0]=='lambda'){ var alpha_function=function(x,y){ var n=[{},{}]; for (var key in rename[0]) { n[0][key]=rename[0][key]; } for (var key in rename[1]) { n[1][key]=rename[1][key]; } for (var i in y[2]){ if(isString(y[2][i]) && isString(x[2][i]) && y[2][i]!=x[2][i]){ n[0][y[2][i]]=x[2][i]; n[1][x[2][i]]=y[2][i]; } else if(isArray(y[2][i]) && isArray(x[2][i]) && y[2][i][0]==x[2][i][0] && y[2][i][0] in set(['[]','()'])){ if(!alpha_impl(x[2][i],y[2][i],n,last_rename,true)){ return false; } } } alpha_impl(x[1],y[1],[{},{}],last_rename,match); for (var i in y[2]){ if(!alpha_impl(x[2][i],y[2][i],n,last_rename,match)){ return false; } } return alpha_impl(x[3],y[3],n,last_rename,match); } if(x[2].length==y[2].length){ return alpha_function(x,y); } else if(u && x[2].length==y[2].length+1 && x[2][x[2].length-1][0]=='~' && x[2][x[2].length-1][2]==2){ if(alpha_impl(x[2][x[2].length-1,['()',[]]],rename,last_rename,match)){ return alpha_function([x[0],x[1],x[2].slice(0,-1),x[3]],y); } else{ return false; } } else if(u && y[2].length==x[2].length+1 && y[2][y[2].length-1][0]=='~' && y[2][y[2].length-1][2]==2){ if(alpha_impl(['()',[]],y[2][y[2].length-1],rename,last_rename,match)){ return alpha_function(x,[y[0],y[1],y[2].slice(0,-1),y[3]]); } else{ return false; } alpha_impl(x[1],y[1],[{},{}],last_rename,match); alpha_impl(['()',[]],y[2][0],rename,last_rename,match) return alpha_impl(x[3],y[3],rename,last_rename,match); } else if(u && nonEmpty(y[2]) && x[2].length>y[2].length){ var last=y[2][y[2].length-1]; if(isArray(last) && nonEmpty(last) && last[0]=='~' && last[2]==2 && alpha_impl(['()',x[2].slice(y[2].length-1,x[2].length)],last,rename,last_rename,match)){ return alpha_function([x[0],x[1],x[2].slice(0,y[2].length-1),x[3]],[y[0],y[1],y[2].slice(0,-1),y[3]]); } else{ return false; } } else if(u && nonEmpty(x[2]) && x[2].length<y[2].length){ var last=x[2][x[2].length-1]; if(isArray(last) && nonEmpty(last) && last[0]=='~' && last[2]==2 && alpha_impl(['()',y[2].slice(x[2].length-1,y[2].length)],last,rename,last_rename,match)){ return alpha_function([x[0],x[1],x[2].slice(0,-1),x[3]],[y[0],y[1],y[2].slice(0,x[2].length-1),y[3]]); } else{ return false; } } else{ return false; } } else if(x[0] in set(['def','def_const','def!','def!_const'])){ return false; } } else if(isEmpty(x) && isEmpty(y)){ return true; } else{ return false; } } else if(!isArray(x) && !isArray(y)){ if((y in rename[0])){ y=rename[0][y]; } else if(!(y in rename[0]) && (y in rename[1])){ return false; } return x===y; } else{ return false; } } return alpha_impl(x,y,[{},{}],[{},{}],false); } var U=function(x,y,cont){ while(x in valE) x=valE[x]; while(y in valE) y=valE[y]; if(x==y){ return cont.bind(null,true); } else if(isArray(x) && isArray(y)){ if(nonEmpty(x) && x[0]=='Ast' && nonEmpty(y) && y[0]=='Ast'){ return cont.bind(null,Alpha(x[1],y[1],true)); } else if((nonEmpty(x) && x[0]=='Ast') || (nonEmpty(y) && y[0]=='Ast')){ return cont.bind(null,false); } else{ if(x.length!=y.length){ return cont.bind(null,false); } else{ var L=function(i,cont){ if(i<x.length){ return unify_impl.bind(null,x[i],y[i],function(v){ if(v){ return L.bind(null,i+1,cont); } else{ return cont.bind(null,false); } }); } else{ return cont.bind(null,true); } } return L.bind(null,0,cont); } } } else if(isFunction(x) && isFunction(y) && x(2)!='lambda_continuation' && x(2)!='lambda_continuation'){ return cont.bind(null,Alpha(x(-1),y(-1))); } else if(isString(x)){ valE[x]=y; return cont.bind(null,true); } else if(isString(y)){ valE[y]=x; return cont.bind(null,true); } else if((isBoolean(x)||isBoolean(y)) && toBoolean(x)==toBoolean(y)){ return cont.bind(null,true); } else{ return cont.bind(null,false); } } if((_n(3)=='delay_expr' && _m(3)!='delay_expr') || (_n(3)!='delay_expr' && _m(3)=='delay_expr')){ if(_m(3)=='delay_expr'){ var _t=_n;_n=_m;_m=_t; } return _m().bind(null,null,function(vy){ if(isFunction(vy) && vy(2)=='free_identifier'){ valE['~'+vy(3)]=_n; return cont.bind(null,true); } else if(isFunction(vy) && vy(2)=='Ast'){ vy=['Ast',vy(-1)]; } return _n().bind(null,null,function(vx){ if(isFunction(vx) && vx(2) in set(['free_identifier','Ast'])){ vx=vx(2)=='Ast'?['Ast',vx(-1)]:'~'+vx(3); } return U.bind(null,vx,vy,cont); }); }); } else{ return _n().bind(null,null,function(vx){ return _m().bind(null,null,function(vy){ if(isFunction(vx) && vx(2) in set(['free_identifier','Ast'])){ vx=vx(2)=='Ast'?['Ast',vx(-1)]:'~'+vx(3); } if(isFunction(vy) && vy(2) in set(['free_identifier','Ast'])){ vy=vy(2)=='Ast'?['Ast',vy(-1)]:'~'+vy(3); } return U.bind(null,vx,vy,cont); }); }); } } return unify_impl.bind(null,n,m,function(r){ if(r){ var nv={}; var keys=Object.keys(valE); var L=function(i,cont0){ if(i<keys.length){ return equivalent_value.bind(null,valE[keys[i]],function(x){ nv[keys[i].replace(/^~/,'')]=isFunction(x)&&x(3)=='delay_expr'?x:val_func(x); return L.bind(null,i+1,cont0); },function(){ return cont.bind(null,[false,{}]); }); } else{ return cont0.bind(null); } } return L.bind(null,0,function(){ return cont.bind(null,[r,nv]); }); } else{ return cont.bind(null,[false,{}]); } }); } var evaluate_ast_expr=function(_t, _eval, _env, _gsym, cont){ if(isArray(_t)){ if(nonEmpty(_t)){ if(_t[0] in set(['->','!=','<=','>=','<','>','=','+','-','*','/','%','^','!','<-','_'])){ return evaluate_ast_expr.bind(null,_t[1], _eval, _env, _gsym, function(x){ return evaluate_ast_expr.bind(null,_t[2], _eval, _env, _gsym, function(y){ return cont.bind(null,[_t[0],x,y]); }); }); } else if(_t[0]=='\\()\\'){ return _eval.bind(null,_t[1], _env, _gsym, function(x){ var r=x(-1); if(isArray(r) && nonEmpty(r) && r[0]=='()'){ r.push(true); } else if(isArray(r) && nonEmpty(r) && r[0]=='~'){ r[2]=2; } return cont.bind(null,r); }); } else if(_t[0]=='\\{}\\'){ return _eval.bind(null,_t[1], _env, _gsym, function(x){ return cont.bind(null,x(-1)); }); } else if(_t[0]=='()'){ return map_cps.bind(null,function(x,cont){ return evaluate_ast_expr.bind(null,x, _eval, _env, _gsym, cont); }, _t[1], function(x){ var ret=[]; x.forEach(function(item,index){ if(isArray(item) && item.length==3 && item[0]=='()' && item[2]){ ret=ret.concat(item[1]); } else{ ret.push(item); } }); return cont.bind(null,['()',ret]); }); } else if(_t[0]=='[]'){ return cont.bind(null,_t); } else if(_t[0]=='#'){ return cont.bind(null,_t); } else if(_t[0]=='~'){ return evaluate_ast_expr.bind(null, _t[1], _eval, _env, _gsym, function(x){ if(isString(x) || x==null || (isArray(x)&&nonEmpty(x)&&x[0]=='#')){ return cont.bind(null,['~',x]); } else{ do_raise("expect identifier, given: "+AstToString(x).replace(/\n$/,'')); } }); } else if(_t[0] in set(['delay','callcc','eval','curry'])){ return evaluate_ast_expr.bind(null,_t[1], _eval, _env, _gsym, function(x){ return cont.bind(null,[_t[0],x]); }); } else if(_t[0]=='|'){ return map_cps.bind(null,function(x,cont){ return evaluate_ast_expr.bind(null, x[0], _eval, _env, _gsym, function(y){ return evaluate_ast_expr.bind(null, x[1], _eval, _env, _gsym, function(z){ return cont.bind(null,[y,z]); }); }); }, _t[1], function(x){ return cont.bind(null,['|',x]); }); } else if(_t[0]=='None'){ return cont.bind(null,_t); } else if(_t[0]=='lambda'){ var err=function(t,msg){ var errcode=AstToString(t).replace(/\n$/,''); errcode=errcode.indexOf('\n')==-1?errcode:'\n'+indent(errcode); do_raise(msg+errcode); } return evaluate_ast_expr.bind(null, _t[1], _eval, _env, _gsym, function(y){ if(!(isString(y)||(isArray(y) && (y[0]=='~' || y[0]=='#')))) err(y,"invaild function name: "); if(_t[2].length==1 && _t[2][0][0]=='\\()\\'){ return evaluate_ast_expr.bind(null, _t[2][0], _eval, _env, _gsym, function(z){ if(isArray(z) && z[0]=='()'){ z[1].forEach(function(item,index){ if(!(isString(item)||(isArray(item) && (item[0] in set (['#','~','lambda','[]','()'])))|| isNumber(item) || item==null)){ err(_t[2][0],"invaild function argument: "); } }); z=z[1]; return evaluate_ast_expr.bind(null, _t[3], _eval, _env, _gsym, function(v){ return cont.bind(null,['lambda',y,z,v]); }); } else if((isString(z) && z=='None') || z==null || (isArray(z) && z[0]=='None')){ return evaluate_ast_expr.bind(null, _t[3], _eval, _env, _gsym, function(v){ return cont.bind(null,['lambda',y,[],v]); }); } else if(isString(z)||(isArray(z) && (z[0] in set (['#','~','lambda','[]','()'])))|| isNumber(z) || z==null){ z=[z]; return evaluate_ast_expr.bind(null, _t[3], _eval, _env, _gsym, function(v){ return cont.bind(null,['lambda',y,z,v]); }); } else{ err(_t[2][0][1],"invaild function argument: "); } }); } else{ return map_cps.bind(null,function(x,cont){ return evaluate_ast_expr.bind(null, x, _eval, _env, _gsym, function(x0){ if(!isString(x0) && !(isNumber(x0) || x0==null) && !(isArray(x0) && nonEmpty(x0) && x0[0] in set (['#','~','lambda','[]','()'])) && !(isArray(x0) && x0.length==3 && x0[0]=='()' && x0[2])) err(x0,"invaild function argument: "); return cont.bind(null,x0); }); }, _t[2], function(z){ var args=[]; z.forEach(function(item,index){ if(isArray(item) && item.length==3 && item[0]=='()' && item[2]){ item[1].forEach(function(item0,index0){ if(!isString(item0) && !(isArray(item0) && nonEmpty(item0) && item0[0] in set (['#','~','lambda','[]','()'])) && !(isNumber(item) || item==null)){ err(item0,"invaild function argument: "); } }); args=args.concat(item[1]); } else{ args.push(item); } }); return evaluate_ast_expr.bind(null, _t[3], _eval, _env, _gsym, function(v){ return cont.bind(null,['lambda',y,args,v]); }); }); } }); } } else{ return cont.bind(null,null); } } else{ return cont.bind(null,_t); } } var evaluate_match_expr=function(_t, _eval, _env, _gsym, cont){ return _eval.bind(null,_t[1], _env, _gsym, function(value){ if(isArray(_t[2]) && isEmpty(_t[2])){ return cont.bind(null,val_func(null)); } else{ if(isArray(_t[2]) && nonEmpty(_t[2]) && _t[2][0]=='|'){ var match_expr_impl=(function(_expr, _eval, _env, _gsym, cont){ if(isEmpty(_expr)){ return cont.bind(null,val_func(null)); } else if(_expr.length==1){ if(_expr[0][0]==null){ return _eval.bind(null,_expr[0][1], _env, _gsym, function(x){ return x().bind(null,null,function(y){ return cont.bind(null,val_func(y)); }); }); } else{ return _eval.bind(null,_expr[0][0], _env, _gsym, function(x){ return unify.bind(null, value, x, function(u){ if(u[0]){ var e=u[1]; merge_dict(e, _env); return _eval.bind(null, _expr[0][1], e, _gsym, function(y){ return y().bind(null,null,function(z){ return cont.bind(null,val_func(z)); }); }); } else{ return cont.bind(null,val_func(null)); } }); }); } } else{ return _eval.bind(null, _expr[0][0], _env, _gsym, function(x){ return unify.bind(null, value, x, function(u){ if(u[0]){ var e=u[1]; merge_dict(e, _env); return _eval.bind(null,_expr[0][1], e, _gsym, function(y){ return y().bind(null,null,function(z){ return cont.bind(null,val_func(z)); }); }); } else{ return match_expr_impl.bind(null,_expr.slice(1),_eval,_env,_gsym,cont); } }); }); } }); return match_expr_impl.bind(null,_t[2][1],_eval,_env,_gsym,cont); } else{ return _eval.bind(null, _t[2], _env, _gsym, cont); } } }); } var evaluate=function(_t, _env, _gsym, cont){ if(isArray(_t)){ if(nonEmpty(_t)){ if(_t[0] in set(['!=','<=','>=','<','>','=','+','-','*','/','%','^','!','<-','_'])){ return evaluate.bind(null,_t[1], _env, _gsym, function(x){ return evaluate.bind(null,_t[2], _env, _gsym, function(y){ return combinator(_t[0]).bind(null,x,y,cont); }); }); } else if(_t[0]=='()'){ return map_cps.bind(null,function(x,cont){ return evaluate.bind(null,x,_env,_gsym,cont); }, _t[1], function(x){ return cont.bind(null,val_func(x)); }); } else if(_t[0]=='[]'){ return evaluate_ast_expr.bind(null,_t[1], evaluate, _env, _gsym, function(x){ return cont.bind(null,val_func(ast_func(x, _env, _gsym))); }); } else if(_t[0]=='|'){ return evaluate.bind(null,['->',true,_t], _env, _gsym, cont); } else if(_t[0]=='->'){ return evaluate_match_expr.bind(null,_t, evaluate, _env, _gsym, cont); } else if(_t[0]=='~'){ if(isString(_t[1]) && (_t[1] in _env || _t[1] in _gsym) && _t[2]!=-1){ return cont.bind(null,environment(_env, _gsym)(_t[1])); } else{ return cont.bind(null,val_func(free_identifier_func(_t[1]))); } } else if(_t[0]=='#'){ if(_t.length==5){ return cont.bind(null,environment(_t[3], _t[4])(_t[1])); } else{ return cont.bind(null,environment(_env, _gsym)(_t[1])); } } else if(_t[0]=='None'){ return cont.bind(null,val_func(null)); } else if(_t[0]=='lambda'){ return cont.bind(null,val_func(func( _t[0], isArray(_t[1]) && _t[1][0]=='~' ? _t[1][1] : isString(_t[1]) ? _t[1] : do_raise("invaild function name: "+AstToString(_t[1]).replace(/\n$/,'')), [_t[2].map(function(arg){ return (isArray(arg) && arg[0]=='~' ? arg[1] : isNumber(arg) || arg==null || isString(arg) && nonEmpty(arg) ? arg : isArray(arg) && nonEmpty(arg) && arg[0] in set (['#','~','lambda','[]','()']) ? arg : do_raise("invaild function argument: "+AstToString(arg).replace(/\n$/,''))); })], [_t[3]], _env, _gsym, evaluate))); } else if(_t[0]=='delay'){ return cont.bind(null,delay_func(_t[1], _env, _gsym, evaluate)); } else if(_t[0]=='callcc'){ return evaluate.bind(null,_t[1], _env, _gsym, function(f){ return f().bind(null,null,function(func){ if(isFunction(func) && func(2)!='value'){ return func().bind(null,[val_func(continuation_func(cont))],cont); } else{ return result_of.bind(null, f, function(v){ do_raise("calling a not callable object "+v); }); } }); }); } else if(_t[0]=='eval'){ return evaluate.bind(null, _t[1], _env, _gsym, function(x){ return x().bind(null,null,function(v){ if(v(2)!='Ast'){ return cont.bind(null,x); } else{ return evaluate.bind(null, v(-1), _env, _gsym, function(v0){ return cont.bind(null,v0); }); } }); }); } else if(_t[0]=='curry'){ return evaluate.bind(null,_t[1], _env, _gsym, function(x){ return x().bind(null,null,function(v){ return cont.bind(null,val_func(curry_func(v))); }); }); } else if(_t[0] in set(['def','def_const','def!','def!_const'])){ do_raise("invaild evaluate on macro <"+_t[1]+">"); } } else{ return cont.bind(null,val_func(null)); } } else{ if(!isNaN(_t)){ return cont.bind(null,val_func(_t)); } else if(isString(_t)){ return cont.bind(null,environment(_env, _gsym)(_t)); } else{ return cont.bind(null,val_func(null)); } } } var indent=function(code){ return code.replace(/\n(?!$)/g,'\n\t').replace(/^(?!\n)/g,'\t'); } var AstToString=function(Ast){ var remove_parentheses=function(str){ var pStack=[], pPair=[]; var lflag=true,rflag=true; var remove_set={}; var ret=''; for(var i in str){ if(str[i]=='('){ if(nonEmpty(pStack)){ pStack[pStack.length-1][1]=lflag; } pStack.push([i,false]); lflag=true; rflag=false; } if(str[i]==')'){ var p=pStack.pop(); if(p[1]&&rflag){ pPair.push([p[0],i]); } rflag=true; lflag=false; } if(!(str[i] in set ([' ','\n','(',')']))){ lflag=false; rflag=false; } } for(var i in pPair){ remove_set[pPair[i][0]]=true; remove_set[pPair[i][1]]=true; } for(var i in str){ if(!(i in remove_set)){ ret+=str[i]; } } return ret; } var AstToString_impl=function(_t){ if(isArray(_t)){ if(nonEmpty(_t)){ if(_t[0] in set(['!=','<=','>=','<','>','=','+','-','*','/','!'])){ return '('+AstToString_impl(_t[1])+_t[0]+AstToString_impl(_t[2])+')'; } if(_t[0] in set(['^','_'])){ return AstToString_impl(_t[1])+_t[0]+'{'+AstToString_impl(_t[2])+'}'; } else if(_t[0]=='<-'){ var f=AstToString_impl(_t[1]); var p=f.match(/(\-\>|[<>=]{2}|\!\=|_(?=\s|\{|\()|[\>\<\=\+\-\*\/\(\)\^\!\:\,\n\|\t\{\}\[\]\ ])/g); return (p?'(':'')+f+(p?')':'')+AstToString_impl(_t[2]).replace(/^{/g,'(').replace(/}$/g,')'); } else if(_t[0]=='->'){ var s1=AstToString_impl(_t[1]); var s2=AstToString_impl(_t[2]); if(s2.indexOf('\n')==-1 && s2.length<48) return '('+s1+_t[0]+s2+')'; else return '('+s1+_t[0]+indent(s2)+')'; } else if(_t[0]=='()'){ var LB=_t[1].length>1?'(':'{'; var RB=_t[1].length>1?')':'}'; var ret=LB+(_t[1].map(function(x){ return AstToString_impl(x); })).join(',')+RB; if(ret.indexOf('\n')==-1 || ret.length<48){ return ret; } else{ return LB+'\n'+indent((_t[1].map(function(x){ return AstToString_impl(x); })).join(',\n'))+'\n'+RB; } } else if(_t[0]=='[]'){ var LB='['; var RB=']'; var code=AstToString_impl(_t[1]); var ret=LB+code+RB; if(ret.indexOf('\n')==-1 || ret.length<48){ return ret; } else{ return LB+'\n'+indent(code)+'\n'+RB; } } else if(_t[0] in set(['\\()\\','\\{}\\'])){ var LB=_t[0].slice(0,2); var RB=_t[0].slice(2); var code=AstToString_impl(_t[1]); var ret=LB+code+RB; if(ret.indexOf('\n')==-1 || ret.length<48){ return ret; } else{ return LB+'\n'+indent(code)+'\n'+RB; } } else if(_t[0]=='#'){ //return _t[1]+':'+_t[2]; return _t[1]; } else if(_t[0]=='~'){ return '~'+AstToString_impl(_t[1]); } else if(_t[0]=='|'){ var temp='\n'; for (var i in _t[1]){ var cond=AstToString_impl(_t[1][i][0]); var expr=AstToString_impl(_t[1][i][1]); if(nonEmpty(expr) && expr[0]=='(' && expr[expr.length-1]==')') expr=expr.slice(1,-1); if(expr.indexOf('\n')==-1){ temp+='| '+cond+': ('+expr+')\n'; } else{ temp+='| '+cond+': ('+indent(expr)+')\n'; } } return temp; } else if(_t[0]=='None'){ return 'None'; } else if(_t[0]=='lambda' || _t[0] in set(['def','def_const','def!','def!_const'])){ var type=_t[0].replace(/_const$/,''); var temp=''; var body=AstToString_impl(_t[3]); var indent_body=(body.indexOf('|')!=-1 || body.indexOf(type)!=-1) || body.length>24; temp+='('+type+':'; if(_t[1]==''){ temp+=_t[2].map(function(x){ return AstToString_impl(x); }).join(',').replace(/(\\\([\S\s]*?\)\\|\\\{[\S\s]*?\}\\)|~/g,'$1'); temp+='->'; } else{ var func=AstToString_impl(_t[1]); var args=_t[2].map(function(x){ return AstToString_impl(x); }).join(',').replace(/(\\\([\S\s]*?\)\\|\\\{[\S\s]*?\}\\)|~/g,'$1'); var title; if(args.length<=36){ title=func+'('+args+')'; } else{ title=func+'(\n'+indent(_t[2].join(',\n'))+'\n)'; } if(indent_body&&title.length>8){ temp+='\n\t'; body=indent(body); } temp+=title+'='; } if(indent_body){ temp+='\n'; temp+=indent(body)+'\n)'; } else{ temp+=body+')'; } return temp; } else if(_t[0]=='delay'){ return 'delay('+AstToString_impl(_t[1])+')'; } else if(_t[0]=='callcc'){ return 'callcc('+AstToString_impl(_t[1])+')'; } else if(_t[0]=='eval'){ return 'eval('+AstToString_impl(_t[1])+')'; } else if(_t[0]=='curry'){ return 'curry('+AstToString_impl(_t[1])+')'; } } return ''; } else{ if(!isNaN(_t)){ if(_t!=null){ return _t.toString(); } else{ return ''; } } else if(isString(_t)){ return _t; } else{ return ''; } } } return remove_parentheses(AstToString_impl(Ast)). replace(/\n\t+\n/g,'\n'). replace(/\n+/g,'\n')+'\n'; } var result_of=function(x, cont){ return x(1).bind(null, cont); } this.execute=function(__Str, cont){ self.halt=false; trampoline_exec(macro_expansion.bind(null,parser(lexer(__Str)),function(Ast){ var t=global_symtable(Ast); return cont.bind(null, function(f, args, cont){ if(f in t){ trampoline_exec(t[f]()(null, function(f){ return f().bind(null, args, function(ret){return result_of.bind(null, ret, cont);}); })); } else{ cont('None'); } }); })); } this.terminate=function() { this.halt=true; } } var addGlobalStyle = (function(css) { var head, style; head = document.getElementsByTagName('head')[0]; if (!head) { return; } style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css; head.appendChild(style); }); function code_console(e, code) { this.element = e; this.continuation; this.inSuspend=false; this.inRuning=false; this.interp = new interpreter(this); this.disabled_input = true; var self = this; this.error=function(msg){ self.inRuning=false; self.interp.terminate(); var history=self.element.find(".output span"); if(history.length>=100){ history.first().next().remove(); history.first().remove(); } var command=$('<span class="error"></span>'); command.text(msg); var output=self.element.find(".output"); output.append(command); output.append('<br>'); output.animate({scrollTop: output.prop("scrollHeight")}); } this.output=function(str){ var history=self.element.find(".output span"); if(history.length>=100){ history.first().next().remove(); history.first().remove(); } var command=$('<span class="result"></span>'); command.html('>>> '+highlight(str)); var output=self.element.find(".output"); output.append(command); output.append('<br>'); output.animate({scrollTop: output.prop("scrollHeight")}); } this.input=function(cont){ self.element.find("textarea").removeClass('disabled'); self.disabled_input = false; self.continuation=cont; } this.suspend=function(cont){ self.element.find("textarea").removeClass('disabled'); self.disabled_input = false; self.element.find("textarea").attr("placeholder","Resume to run? [Y/N]"); self.inSuspend=true; self.continuation=cont; } this.clear=function(cont){ self.element.find("pre.output").empty(); } this.sleep=function(cont, time){ setTimeout(function(){ try { cont(); } catch(err) { if(err.name!='Error'){ err.message='Error: '+err.message; } self.error(err.message); } }, time); } this.halt=function(cont){ self.inRuning=false; self.interp.terminate(); } this.element.find("textarea").keydown(function(e) { if(self.disabled_input){ e.preventDefault(); return; } var code = e.keyCode ? e.keyCode : e.which; if (code == 13) { // Enter keycode e.preventDefault(); if(self.inSuspend){ var input=$(this).val().replace(/\n|\r\n/g,'').trim(); $(this).val(''); if(input.toUpperCase()=='Y'){ $(this).attr("placeholder",""); $(this).addClass('disabled'); self.disabled_input=true; self.inSuspend=false; try { self.continuation(); } catch(err) { if(err.name!='Error'){ err.message='Error: '+err.message; } error(err.message); } } else if(input.toUpperCase()=='N'){ $(this).attr("placeholder",""); $(this).prop('disabled', true); self.inSuspend=false; } } else if ($(this).val().trim().length > 0) { var input=$(this).val().trim(); var command=$('<span class="command"></span>'); command.html(highlight(input)); var output=self.element.find(".output"); output.append(command); output.append('<br>'); $(this).addClass('disabled'); $(this).val(''); self.disabled_input=true; output.animate({scrollTop: output.prop("scrollHeight")}); try { self.continuation(input); } catch(err) { if(err.name!='Error'){ err.message='Error: '+err.message; } self.error(err.message); } } } }); var description = code.match(/(?:\/\/ [^\n]*\n)+(?:\/\/ ==description==\n)((?:\/\/ [^\n]*\n)*)(?:\/\/ ==description==\n)/); if(description) { var output=self.element.find(".output"); description = description[1].replace(/^\/\/ /mg,"") .replace(/\n$/, "") .split("\n"); description.forEach(function(d){ var command=$('<span class="description"></span>'); command.text(d); output.append(command); output.append('<br>'); }); output.append('<br>'); } if(!self.inRuning) { if (code.length > 0) { //self.interp.execute(code,function(exce){ // exce('f',[],self.output); //}); try { self.element.find(".run span").text("Runing"); self.element.find("textarea").attr("placeholder",""); self.element.find("textarea").addClass('disabled'); self.element.find("textarea").val(''); self.disabled_input=true; self.inSuspend=false; self.inRuning=true; self.interp.execute(code,function(exce){ exce('f',[],function(x){ self.inRuning=false; self.output(x); }); }); } catch(err) { if(err.name!='Error'){ err.message='Error: '+err.message; } self.error(err.message); } } } } function uuidv4() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } var code_console_list = {}; function create_console(e) { if(e.innerText.match(/^\/\/ Shirayuki script\n/)) { e.setAttribute("style", "display:none;"); var con = document.createElement("DIV"); con.className = "console"; con.id = uuidv4(); con.innerHTML = `<pre class="output"></pre><div class="input" style='height: 23px;'><textarea rows="1"></textarea></div><div class="shadow"></div>`; e.parentNode.insertBefore(con, e.nextSibling); e.parentNode.classList.add("console_container"); code_console_list[con.id] = new code_console($(con), e.innerText); } } [...document.getElementsByTagName("code")].forEach(create_console); var mb = new MutationObserver(function (mutations) { try { mutations.forEach(mutation => { if (mutation.addedNodes) { mutation.addedNodes.forEach(node => { if(node.nodeType === Node.ELEMENT_NODE) { var code = node.getElementsByTagName("code"); if(code && code.length) { [...code].forEach(e => { create_console(e); }); } } }); } if (mutation.removedNodes) { mutation.removedNodes.forEach(node => { if(node.nodeType === Node.ELEMENT_NODE) { var code_console = node.querySelectorAll("div.console"); if(code_console && code_console.length) { [...code_console].forEach(e => { if(e.id && e.id in code_console_list) { code_console_list[e.id].halt(); delete code_console_list[e.id]; } }); } } }); } }); } catch(e) { console.log(e); } }); function escapeHtml(string) { var entityMap = { " ": " ", "&": "&", "<": "<", ">": ">", '"': '"', "'": ''', "/": '/' }; return String(string).replace(/[&<>"'\/ ]/g, function (s) { return entityMap[s]; }); } function highlight(src){ var length=src.length; var bIndex=0; var bStack=[]; var sbIndex=0; var sbStack=[]; var cbIndex=0; var cbStack=[]; var escapeStack=[]; var matchStack=[]; var status=[ function(x){ if(x.length==0){ return ['','']; } var t=x.match(/^\/\/[^\n]*/); if(t){ return ['<span class="comment">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\b(?:def!|(?:lambda|def)\b)/); if(t){ cur=1; return ['<span class="keyword">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\b(?:delay|callcc|eval|curry)\b/); if(t){ return ['<span class="keyword">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\b(?:(?:-)?[0-9.]+|None|false|true)\b/); if(t){ return ['<span class="number">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\b(?:[A-Za-z0-9]|_(?!\{|\(|\s))+/); if(t){ return ['<span name="__'+t[0]+'" class="identifier">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^(?:[<>=]{2}|\!\=|[\<\>\=\+\-\*\/\%\^\!\_])/); if(t){ return ['<span class="operator">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^(?:\\(?:\{|\())/); if(t){ escapeStack.push(cur); cur=0; return ['<span class="operator">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^(?:(?:\}|\))\\)/); if(t){ if(escapeStack.length>0){ cur=escapeStack.pop(); } return ['<span class="operator">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\|/); if(t){ cur=3; return [t[0],x.slice(t[0].length)]; } t=x.match(/^\(/); if(t){ bStack.push(bIndex); return ['<span name="_B_'+(bIndex++)+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\)/); if(t){ if(matchStack.length>0 && bStack.length==matchStack[matchStack.length-1][0]){ cur=matchStack.pop()[1]; } var index; if(bStack.length>0){ index=bStack.pop(); } else{ index=-1; } return ['<span name="_B_'+index+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\[/); if(t){ sbStack.push(sbIndex); escapeStack.push(cur); cur=0; return ['<span name="_SB_'+(sbIndex++)+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\]/); if(t){ var index; if(sbStack.length>0){ index=sbStack.pop(); } else{ index=-1; } if(escapeStack.length>0){ cur=escapeStack.pop(); } return ['<span name="_SB_'+index+'" id="_bracket_at_'+(length-x.length)+'" class="'+(cur==3?'condition ':'')+'bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\{/); if(t){ cbStack.push(cbIndex); return ['<span name="_CB_'+(cbIndex++)+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\}/); if(t){ var index; if(cbStack.length>0){ index=cbStack.pop(); } else{ index=-1; } return ['<span name="_CB_'+index+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^,/); if(t){ if(matchStack.length>0 && bStack.length==matchStack[matchStack.length-1][0]){ cur=matchStack.pop()[1]; } return [escapeHtml(x[0]),x.slice(1)]; } return [escapeHtml(x[0]),x.slice(1)]; }, function(x){ if(x.length==0){ return ['','']; } var t=x.match(/^\/\/[^\n]*/); if(t){ return ['<span class="comment">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^(?:\\(?:\{|\())/); if(t){ escapeStack.push(2); cur=0; return ['<span class="operator">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^(?:(?:\}|\))\\)/); if(t){ if(escapeStack.length>0){ cur=escapeStack.pop(); } return ['<span class="operator">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\b(?:([A-Za-z_][A-Za-z0-9_]*)(?=\s*(?:\(|=)))\b/); if(t){ cur=2; return ['<span name="__'+t[0]+'" class="function">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\b(?:[A-Za-z_][A-Za-z0-9_]*)\b/); if(t){ return ['<span name="__'+t[0]+'" class="parameter">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^(?:=|->)/); if(t){ cur=0; return [escapeHtml(t[0]),x.slice(t[0].length)]; } t=x.match(/^\(/); if(t){ bStack.push(bIndex); return ['<span name="_B_'+(bIndex++)+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\)/); if(t){ var index; if(bStack.length>0){ index=bStack.pop(); } else{ index=-1; } return ['<span name="_B_'+index+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\[/); if(t){ sbStack.push(sbIndex); escapeStack.push(cur); cur=0; return ['<span name="_SB_'+(sbIndex++)+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\]/); if(t){ var index; if(sbStack.length>0){ index=sbStack.pop(); } else{ index=-1; } if(escapeStack.length>0){ cur=escapeStack.pop(); } return ['<span name="_SB_'+index+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\{/); if(t){ cbStack.push(cbIndex); return ['<span name="_CB_'+(cbIndex++)+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\}/); if(t){ var index; if(cbStack.length>0){ index=cbStack.pop(); } else{ index=-1; } return ['<span name="_CB_'+index+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } return [escapeHtml(x[0]),x.slice(1)]; }, function(x){ if(x.length==0){ return ['','']; } var t=x.match(/^\/\/[^\n]*/); if(t){ return ['<span class="comment">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^(?:\\(?:\{|\())/); if(t){ escapeStack.push(cur); cur=0; return ['<span class="operator">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^(?:(?:\}|\))\\)/); if(t){ if(escapeStack.length>0){ cur=escapeStack.pop(); } return ['<span class="operator">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\blambda\b/); if(t){ matchStack.push([bStack.length,cur]); cur=0; return ['<span class="keyword">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\b(?:(?:-)?[0-9.]+|None|false|true)\b/); if(t){ return ['<span class="number">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\b(?:[A-Za-z_][A-Za-z0-9_]*)\b/); if(t){ return ['<span name="__'+t[0]+'" class="parameter">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^(?:=|->)/); if(t){ cur=0; return [escapeHtml(t[0]),x.slice(t[0].length)]; } t=x.match(/^\(/); if(t){ bStack.push(bIndex); return ['<span name="_B_'+(bIndex++)+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\)/); if(t){ cur=1; var index; if(bStack.length>0){ index=bStack.pop(); } else{ index=-1; } return ['<span name="_B_'+index+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\[/); if(t){ sbStack.push(sbIndex); escapeStack.push(cur); cur=0; return ['<span name="_SB_'+(sbIndex++)+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\]/); if(t){ var index; if(sbStack.length>0){ index=sbStack.pop(); } else{ index=-1; } if(escapeStack.length>0){ cur=escapeStack.pop(); } return ['<span name="_SB_'+index+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\{/); if(t){ cbStack.push(cbIndex); return ['<span name="_CB_'+(cbIndex++)+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\}/); if(t){ var index; if(cbStack.length>0){ index=cbStack.pop(); } else{ index=-1; } return ['<span name="_CB_'+index+'" id="_bracket_at_'+(length-x.length)+'" class="bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } return [escapeHtml(x[0]),x.slice(1)]; }, function(x){ if(x.length==0){ return ['','']; } var t=x.match(/^\/\/[^\n]*/); if(t){ return ['<span class="comment">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^(?:\\(?:\{|\())/); if(t){ escapeStack.push(cur); cur=0; return ['<span class="operator">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^(?:(?:\}|\))\\)/); if(t){ if(escapeStack.length>0){ cur=escapeStack.pop(); } return ['<span class="operator">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\b(?:def!|(?:lambda|def)\b)/); if(t){ t0=x.slice(t[0].length).match(/^\s*:/); if(t0){ return ['<span class="condition keyword">'+escapeHtml(t[0])+'</span>'+'<span class="condition">'+escapeHtml(t0[0])+'</span>', x.slice(t[0].length+t0[0].length)]; } else{ return ['<span class="condition keyword">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } } t=x.match(/^\b(?:(?:-)?[0-9.]+|None|false|true)\b/); if(t){ return ['<span class="condition number">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\b[A-Za-z_](?:[A-Za-z0-9]|_(?!\{|\(|\s))*/); if(t){ return ['<span name="__'+t[0]+'" class="condition identifier">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^[^:\\\[\]\(\)\{\}\s\w]+/); if(t){ return ['<span class="condition">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^:/); if(t){ cur=0; return [t[0],x.slice(t[0].length)]; } t=x.match(/^\(/); if(t){ bStack.push(bIndex); return ['<span name="_B_'+(bIndex++)+'" id="_bracket_at_'+(length-x.length)+'" class="condition bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\)/); if(t){ var index; if(bStack.length>0){ index=bStack.pop(); } else{ index=-1; } return ['<span name="_B_'+index+'" id="_bracket_at_'+(length-x.length)+'" class="condition bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\[/); if(t){ sbStack.push(sbIndex); escapeStack.push(cur); cur=0; return ['<span name="_SB_'+(sbIndex++)+'" id="_bracket_at_'+(length-x.length)+'" class="condition bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\]/); if(t){ var index; if(sbStack.length>0){ index=sbStack.pop(); } else{ index=-1; } if(escapeStack.length>0){ cur=escapeStack.pop(); } return ['<span name="_SB_'+index+'" id="_bracket_at_'+(length-x.length)+'" class="condition bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\{/); if(t){ cbStack.push(cbIndex); return ['<span name="_CB_'+(cbIndex++)+'" id="_bracket_at_'+(length-x.length)+'" class="condition bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } t=x.match(/^\}/); if(t){ var index; if(cbStack.length>0){ index=cbStack.pop(); } else{ index=-1; } return ['<span name="_CB_'+index+'" id="_bracket_at_'+(length-x.length)+'" class="condition bracket">'+escapeHtml(t[0])+'</span>',x.slice(t[0].length)]; } return ['<span class="condition">'+escapeHtml(x[0])+'</span>',x.slice(1)]; } ]; var t=src; var r=''; var cur=0; while(t.length>0){ var ret=status[cur](t); r+=ret[0]; t=ret[1]; } return r; } addGlobalStyle(` .console, .console pre.output, .console pre.output span, .console textarea, .console textarea:focus { font-size:14px; line-height:1.3; font-weight: normal; font-family:"Consolas", "Andale Mono", "Courier New", "Courier", monospace; border:0 none; outline:0 none; -webkit-box-shadow:none; -moz-box-shadow:none; box-shadow:none; } .console { position:relative; color: #ddd; background: #333; padding-top:10px; max-width:640px; margin:0px auto; } .console .shadow { position: absolute; left: 0px; top: 10px; right: 0px; bottom: 32px; -webkit-box-shadow: inset 0px 0px 2px 2px #333; -moz-box-shadow: inset 0px 0px 2px 2px #333; box-shadow: inset 0px 0px 2px 2px #333; pointer-events: none; } .console pre.output { background: #333; display:block; white-space:pre; width:calc(100% - 15px); height:120px; overflow-y:auto; overflow-x:auto; position:relative; padding: 0 0 0 15px; margin:0 0 10px; border:0 none; } .console pre.output span { color:#f7f7f7; } .console pre.output span.description { color:#aaa; } .console pre.output span.command { color:#f7f7f7; opacity: 0.7; } .console pre.output span.result { color:#f7f7f7; opacity: 1;} .console pre.output span.error { color:#f77; } .console .input { padding:0 0 0 15px; position:relative; } .console .input:before { content:">"; position:absolute; top: 0; left: 0; color:#ddd } .console textarea { color:#ddd; background:#333; border:0 none; outline:0 none; padding:0; margin:0; resize: none; width:100%; overflow:hidden; } .console textarea:focus { outline:0 none; } .console textarea.disabled{ color:transparent; } .console pre.output::-webkit-scrollbar, .console pre.output::-webkit-scrollbar-button, .console pre.output::-webkit-scrollbar-track, .console pre.output::-webkit-scrollbar-track-piece, .console pre.output::-webkit-scrollbar-thumb, .console pre.output::-webkit-scrollbar-corner, .console pre.output::-webkit-resizer { background: transparent; } .console pre.output::-webkit-scrollbar { width: 7px; height: 7px; -webkit-border-radius: 4px; border-radius: 4px; } .console pre.output::-webkit-scrollbar-track-piece { -webkit-border-radius: 5px; border-radius: 5px; } .console pre.output::-webkit-scrollbar-thumb { background: #4f4f4f; border-radius: 5px; } .console pre.output::-webkit-scrollbar-button { width:0; height:0; } pre.console_container { background: #333; } .console pre.output span.keyword{ font-style: italic; color: #66D9EF; } .console pre.output span.number{ color:#AE81FF; } .console pre.output span.function{ color: #A6E22E; } .console pre.output span.parameter{ font-style: italic; color: #FD971F; } .console pre.output span.comment{ color: #75715E; } .console pre.output span.operator{ color: #F92672; } .console pre.output span.condition{ color: #E6DB74; } `); mb.observe(document.body, { subtree: true, childList: true, attributes: false, characterData: false }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址