function newArray(){
var a=Array.apply(null,arguments);
a._super=Array();
a.toString=function(){ var s="(", first=true;
for(var i=0; i<this.length; i++){
if(first){ first=false }else{ s+="," }
s+=(this[i]==undefined)?"":this[i];
}
return s+")";
}
a.concat= function(){ return toNA( a._super.concat.apply(a,arguments) ) }
//a.join Arrayをそのまま使う
a.unshift=function(){ a._super.unshift.apply(a,arguments); return a }
a.push= function(){ a._super.push.apply(a,arguments); return a }
//a.shift Arrayをそのまま使う
//a.pop Arrayをそのまま使う
a.slice=function(){ return toNA(a._super.slice.apply(a,arguments)) }
a.splice=function(){ return toNA(a._super.splice.apply(a,arguments)) }
//a.reverse Arrayをそのまま使う
//a.sort Arrayをそのまま使う
a.map=function(f){ var r=newArray();
for(var i=0; i<this.length; i++){ r.push(f(a[i],i)); }
return r;
}
a.foldl=function(f,x){ var r=x;
for(var i=0; i<this.length; i++){ r=f(r,a[i]) }
return r;
}
a.keep=function(p){ var r=newArray();
for(var i=0; i<this.length; i++){ if(p(a[i],i)){ r.push(a[i]) } }
return r;
}
return a;
}
function toNA(a){ return newArray.apply(null,a) }
function range(){
if(arguments.length==1) return newArray(arguments[0]).map(function(x,i){return i});
if(arguments.length==2){ var s=arguments[0],r=arguments[1]-s;
return newArray(r).map(function(x,i){ return i+s });
}
return newArray();
}
function sum(na){ return na.foldl(function(x,y){ return x+y },0)}
//ps5.js paser-like ver1.05
ppa=function(a){ return (a instanceof Array)?"["+a+"]":"notArray:"+a }
function pret(v,r){
this.v=v; this.r=r;
this.toString=function(){ return "("+ppa(v)+","+r+")" }
}
fail=new pret([],"");
fail.toString=function(){ return "*fail*" }
function pa(p){
this.p=p;
this.$=function(f){ return new pa(function(s){ var x=p(s); return x==fail?fail:f(x.v).p(x.r) }) }
this.$$=function(p2){ return new pa(function(s){ var x=p(s); return x==fail?fail:p2.p(x.r) })};
this.l=function(p2){ return new pa(function(s){ var x=p(s); return x==fail?p2.p(s):x })};
}
ret=function(v){ return new pa(function(s){ return new pret(v,s) }) }
hd= function(s){ return s.substr(0,1) }
bd= function(s){ return s.substr(1) }
item=new pa(function(s){ var c=hd(s); return c==""?fail:new pret([c],bd(s)) });
failure=new pa(function(s){ return fail });
// println( ret([1]).p("23") );
// println( item.p("12345") );
// println( failure.p("29") );
sat=function(pred){ return item.$(function(x){ return pred(x[0])?ret(x):failure }) }
isdigit=function(c){ return /[0-9]/.test(c) }
islower=function(c){ return /[a-z]/.test(c) }
isupper=function(c){ return /[A-Z]/.test(c) }
isalpha=function(c){ return /[a-zA-Z]/.test(c) }
isalphanum=function(c){ return /[0-9a-zA-Z]/.test(c) }
is=function(a){ return function(b){ return a==b }}
digit=sat(isdigit);
lower=sat(islower);
upper=sat(isupper);
alpha=sat(isalpha);
alphanum=sat(isalphanum);
chr=function(c){ return sat(is(c)) }
// println( digit.p("123") );
// println( digit.p("abc") );
// println( chr("a").p("abc") );
// println( chr("a").p("123") );
string=function(key){
if(key==""){ return ret([]); }
return chr(hd(key)).$$( string(bd(key)).$$( ret([key]) ) );
}
// println( string("abc").p("abcdef") );
// println( string("abc").p("ab1234") );
// println( string("abc").p("abc") )
many=function(p){ return many1(p).l( ret([]) ) };
many1=function(p){
return p.$( function(v){
return many(p).$( function(vs){
return ret(v.concat(vs)) }) })
};
// println( many(digit).p("123abc") );
// println( many1(digit).p("123abc") );
// println( many(digit).p("abcdef") );
// println( many1(digit).p("abcdef") );
ident= lower.$(function(x){
return many1(alphanum).$(function(xs){
return ret( x.concat(xs) ) }) });
idents= lower.$(function(x){
return many1(alphanum).$(function(xs){
return ret( [x.concat(xs).join("")] ) }) });
nat= many1(digit).$(function(xs){
return ret( [xs.join("")] ) });
isspace=function(c){ return /[\s\t\n]/.test(c) }
space= many(sat(isspace)).$$( ret([]) );
// println( ident.p("abc def") );
// println( idents.p("abc def") );
// println( nat.p("123 abc") );
// println( space.p(" abc") );
token=function(p){
return space.$$(
p.$(function(v){
return space.$$(
ret(v) ) }) )
};
identifier=token(idents);
natural=token(nat);
symbol=function(xs){ return token(string(xs)) }
// println( identifier.p(" abc def") );
// println( natural.p(" 234 abc") );
// println( symbol("test").p(" test test") );
// println( symbol("test").p(" testtest") );
chain=function(p,op){ return new pa(
function(s){
var x1=p.p(s);
if(x1==fail) return fail;
for(;;){
var xop=op.p(x1.r);
if(xop==fail) return x1;
var x2=p.p(xop.r);
if(x2==fail) return fail;
x1=ret( xop.v(x1.v, x2.v) ).p(x2.r);
}
}
)}
plus=symbol("+").$$( ret( function(v1,v2){ return [Number(v1[0])+Number(v2[0])] }) );
mins=symbol("-").$$( ret( function(v1,v2){ return [v1[0]-v2[0]] }) );
mult=symbol("*").$$( ret( function(v1,v2){ return [v1[0]*v2[0]] }) );
divs=symbol("/").$$( ret( function(v1,v2){ return [v1[0]/v2[0]] }) );
// test=chain(natural,plus.l(mins).l(mult).l(divs));
// println( test.p("3+2+1") );
// println( test.p("3-2+1") );
// println( test.p("3+2*2") );
// println( test.p("3/2*2") );
prnop=symbol("(");
prncl=symbol(")");
fact=natural.l(
prnop.$$(
expr.$(function(v){
return prncl.$$(
ret(v) ) }) )
);
term=chain(fact,mult.l(divs));
expr=chain(term,plus.l(mins));
println( expr.p("3-(2+1)"));
println( expr.p("3-2*2"));
println( expr.p("200+2/3-100"));
//javascript shelllike ver1.02
ppa=function(a){ return (a instanceof Array)?"["+a+"]":"notArray:"+a }
function pret(v,r){
this.v=v; this.r=r;
this.toString=function(){ return "("+ppa(this.v)+", "+this.r+")" }
}
fail={v:[],r:"",toString:function(){return "*fail*"}}
bind=function(p,f){ return function(s){ var x=p(s); return x==fail?fail:f(x.v)(x.r) }}
bindn=function(p1,p2){ return function(s){ var x=p1(s); return x==fail?fail:p2(x.r); }}
or=function(p1,p2){ return function(s){ var x; return (x=p1(s))!=fail? x: p2(s) }}
ret=function(v){ return function(s){ return new pret(v,s) }}
item=function(s){ var c; return (c=s.substr(0,1))==""?fail:ret([c])(s.substr(1)) }
failure=function(s){ return fail }
sat=function(p){ return bind(item, function(v){
return p(v[0])?ret(v):failure })
};
isdigit=function(c){ return /[0-9]/.test(c) };
islower=function(c){ return /[a-z]/.test(c) };
isupper=function(c){ return /[A-Z]/.test(c) };
isalpha=function(c){ return /[a-zA-Z]/.test(c) };
isalphanum=function(c){ return /[0-9a-zA-Z]/.test(c) };
digit=sat(isdigit);
lower=sat(islower);
upper=sat(isupper);
letter=sat(isalpha);
alphanum=sat(isalphanum);
chr=function(x){ return sat(function(c){return c==x}) };
//println( digit( "123" ) );
//println( digit( "abc" ) );
//println( chr("a")( "abc" ) );
//println( chr("a")( "123" ) );
/*
string=function(key){
if(key==""){ return ret("") };
return bind( chr(key.substr(0,1)), function(nouse){
return bind( string(key.substr(1)), function(nouse2){
return ret([key]) }) });
};
*/
string=function(key){
if(key==""){ return ret("") };
return bindn( chr(key.substr(0,1)),
bindn( string(key.substr(1)),
ret([key]) ));
}
//println( string("abc")("abcdef") );
//println( string("abc")("ab1234") );
//println( string("abc")("abc") )
many=function(p){ return or(many1(p), ret([])) };
many1=function(p){
return bind( p, function(v){
return bind( many(p), function(vs){
return ret(v.concat(vs)) }) })
}
//println( many(digit)("123abc") );
//println( many(digit)("abcdef") );
//println( many1(digit)("abcdef") );
ident= bind( lower, function(x){
return bind( many(alphanum), function(xs){
return ret( x.concat(xs) ) }) });
nat= bind( many1(digit), function(xs){
return ret( parseInt(xs.join("")) ) });
isspace=function(c){ return /[\s\t\n]/.test(c) }
space= bindn( many(sat(isspace)), ret([]) );
//println( ident("abc def") );
//println( nat("123 abc") );
//println( space(" abc") );
token=function(p){
return bindn(space,
bind(p, function(v){
return bindn(space,
ret(v) ) }) )
};
identifier=token(ident);
natural=token(nat);
symbol=function(xs){ return token(string(xs)) };
//println( identifier(" abc def") );
//println( natural(" 234 abc") );
//println( symbol("test")(" test test") );
//println( symbol("test")(" testtest") );
prnl=token(chr("("));
prnr=token(chr(")"));
plus=token(chr("+"));
mins=token(chr("-"));
var expr;
term=or( natural,
bindn(prnl,
bind(expr, function(v){ return (
bindn(prnr,
ret(v) ) )}) )
);
expr=or(
or(
bind(term, function(v1){ return (
bindn(plus,
bind(expr, function(v2){ return (
ret(v1+v2) )}) ) )}),
bind(expr, function(v1){ return (
bindn(mins,
bind(term, function(v2){ return (
ret(v1-v2) )}) ) )})
),
term
);
function files(dir,name){
var fso=WScript.CreateObject("Scripting.FileSystemObject");
var r=[];
var d=fso.GetFolder(dir);
var e=new Enumerator(d.files);
for(; !e.atEnd(); e.moveNext()){
var p=e.item().path;
if(!name || p.match(name)){ r.push(p) }
}
return r;
}
//パスが長い
//javascript shelllike ver 1.01
function print(s){ WScript.StdOut.Write(s); };
function println(s){ WScript.StdOut.Write(s+"\n"); };
function readline(){ return WScript.StdIn.ReadLine(); };
function printerr(mes,err){ println(mes+err); for(var i in err){ println(i+": "+err[i]) };};
function readfile(name){
var fso=WScript.CreateObject("Scripting.FileSystemObject");
var f=fso.OpenTextFile(name,1,false);
var txt=f.ReadAll();
f.Close();
return txt;
}
function edit(name){ return (new ActiveXObject("WScript.Shell")).Exec("notepad "+name); }
function quit(){ WScript.Quit() }
var _$_P_$_="\n> ";
var _$_S_$_="";
var _$_R_$_="";
var _$_E_$_="";
var _GLOBAL=(function(){return this}).apply(null,[]);
for(;;){
print(_$_P_$_);
_$_S_$_=readline();
try{
if(_$_S_$_.match(/^\s*load\((.*)\)(\s|$)/)){ _$_S_$_=readfile(eval(RegExp.$1)); }
else if(_$_S_$_.match(/^\s*quit(\s|$)/)){ break; }
else{ _$_R_$_=eval(_$_S_$_); }
_$_R_$_=eval(_$_S_$_);
}catch(_$_E_$_){ printerr("eval-err: ", _$_E_$_); continue; }
try{ print(_$_R_$_); }catch(_$_E_$_){ printerr("print-err: ",_$_E_$_); }
}
pret=function(v,r){ return {v:v, r:r, toString:function(){ return "{v:"+v+", r:"+r+"}" } }}
ret=function(v){ return function(r){ return pret(v,r) }}
fail={toString:function(){return "*fail*"}}
failure=function(r){ return fail }
item=function(s){ return (s=="")?fail:pret(s.substring(0,1),s.substring(1)) }
parse=function(p,s){ return p(s) }
bind=function(p,f){ return function(s){ var x; return (x=parse(p,s))==fail?fail:parse(f(x.v), x.r) }};
/*
p= bind(item, function(x){
return bind(item, function(nouse){
return bind(item, function(y){
return ret(x+y) }) }) });
print( parse(p,"abcdef") );
print("\n");
print( parse(p,"ab") );
print("\n");
*/
or=function(p,q){ return function(s){ var x; return (x=parse(p,s))!=fail?x:parse(q,s) }};
/*
print( parse(or(item,ret("d")), "abc") );
print("\n");
print( parse(or(failure,ret("d")), "abc") );
print("\n");
print( parse(or(failure,failure), "abc") );
print("\n");
*/
sat=function(pred){ return bind(item, function(x){
return pred(x)?ret(x):failure }) };
/*
print( parse( sat(function(c){return c=="a"}), "abc" ) );
print("\n");
print( parse( sat(function(c){return c=="a"}), "bbc" ) );
print("\n");
*/
isdigit=function(c){ return c.match(/[0-9]/) };
islower=function(c){ return c.match(/[a-z]/) };
isupper=function(c){ return c.match(/[A-Z]/) };
isalpha=function(c){ return c.match(/[a-zA-Z]/) };
isalphanum=function(c){ return c.match(/[0-9a-zA-Z]/) };
digit=sat(isdigit);
lower=sat(islower);
upper=sat(isupper);
letter=sat(isalpha);
alphanum=sat(isalphanum);
chr=function(x){ return sat(function(c){return c==x}) };
/*
print( parse( digit, "123" ) );
print("\n");
print( parse( digit, "abc" ) );
print("\n");
print( parse( chr("a"), "abc" ) );
print("\n");
print( parse( chr("a"), "123" ) );
print("\n");
*/
strng=function(key){
if(key==""){ return ret("") };
return bind( chr(key.substring(0,1)), function(nouse){
return bind( strng(key.substring(1)), function(nouse2){
return ret(key) }) });
};
/*
print( parse(strng("abc"), "abcdef")+"\n" );
print( parse(strng("abc"), "ab1234")+"\n" );
*/
many=function(p){ return or(many1(p), ret("")) };
many1=function(p){
return bind( p, function(v){
return bind( many(p), function(vs){
return ret(v+vs) }) }) }
/*
print( parse(many(digit), "123abc")+"\n" );
print( parse(many(digit), "abcdef")+"\n" );
print( parse(many1(digit), "abcdef")+"\n" );
*/
ident= bind( lower, function(x){
return bind( many(alphanum), function(xs){
return ret(x+xs) }) });
/*
nat= bind( many1(digit), function(xs){
return ret(parseInt(xs)) });
javascriptでは数値と文字列はあいまいなので、型変換しなくてもよさそうだ
*/
nat=many1(digit);
isspace=function(c){ return c.match(/[\s\t\n]/)};
space= bind(many(sat(isspace)), function(nouse){
return ret("") });
/*
print( parse(ident, "abc def")+"\n" );
print( parse(nat, "123 abc")+"\n" );
print( parse(space, " abc")+"\n" );
*/
token=function(p){
return bind(space, function(nouse){
return bind(p, function(v){
return bind(space, function(nouse2){
return ret(v) }) }) }) };
identifier=token(ident);
natural=token(nat);
symbol=function(xs){ return token(strng(xs)) };
/*
p= bind(symbol("["), function(nouse){
return bind(natural, function(n){
return bind(
many( bind(symbol(","), function(nouse){return natural} )),
function(ns){
return bind(symbol("]"), function(nouse2){
return ret(n+ns) }) }) }) });
print( parse(p, " [1, 2, 3] ")+"\n" );
print( parse(p, " [1, 2,] ")+"\n" );
javascriptは文字列!=charの配列なのでやむなし・・・
*/
plus=token(chr("+"));
p= bind(natural, function(x1){
return bind(plus, function(nouse){
return bind(natural, function(x2){
return ret(parseInt(x1)+parseInt(x2)) }) }) });
とりあえず、メモ書き用にブログを設定してみたよ