- // ==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 });
-
- })();