Shirayuki

Shirayuki language implement

目前為 2018-01-08 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Shirayuki
// @namespace
// @version      1.1
// @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(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(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);});
					}));
				}
			});
		}));
	}

	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);

		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.scrollTop(
				output[0].scrollHeight - output.height()
			);
		}

		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.text('>>> '+str);
			var output=self.element.find(".output");
			output.append(command);
			output.append('<br>');
			output.scrollTop(
				output[0].scrollHeight - output.height()
			);
		}

		this.input=function(cont){
			self.element.find("textarea").prop('disabled', false);
			self.continuation=cont;
		}

		this.suspend=function(cont){
			self.element.find("textarea").prop('disabled', false).focus();
			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) {
			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).prop('disabled', 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.text(input);
					var output=$(".output");
					output.append(command);
					output.append('<br>');
					$(this).val('');
					$(this).prop('disabled', true);
					output.scrollTop(
						output[0].scrollHeight - output.height()
					);
					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',[],con.output);
				//});
				try {
					self.element.find(".run span").text("Runing");
					self.element.find("textarea").attr("placeholder","");
					self.element.find("textarea").prop('disabled', true);
					self.element.find("textarea").val('');
					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" disabled></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);
		}
	});

	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:#aaa; }
	.console pre.output span.result       { color:#f7f7f7; }
	.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 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;
	}
	`);
	mb.observe(document.body, { subtree: true, childList: true, attributes: false, characterData: false });

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址