Grassインタプリタできたよーwww
無駄に長いのでソースは最後wwwww
とりあえず出来が酷いwwww動くか怪しいしwwwwwwwww
完成したのに今一つGrassの動作が解ってないwwwwww意味ねえwwwwwwww
しかもwwwwwErlangぽさがwwwwwwほとんどねえwwwwwwww
仕様wWWwwww:
- 全角のw、WなんてwwwwwwErlangが扱えるわけwwwwwwwねーよwwwwwww
- まともに動くwwwwwwwわけwwwwwねーよwwwwwwwwwwww
サンプル、というか検証に使ったテストコードはirie @ ウィキ - grass.elから(無断でこっそり)お借りしましたww*1
この場でお礼を申し上げますwwwww本当にありがとうございましたwwwwwwwwwwwww*2
ここのHello, world動かなかったwwwwwwwwエラー表示がwwwwww1000行とかwwwwww
実装失敗wwwwwwwww
今後の予定ww:
もしこれ以上wwww弄るwwwとかwwwww
- サーバ化するとwwwwwgen_server辺りの練習にwwwwwwならねえwwwwwwwwwww
- i/1が現状だと残念wwwwwwwすぎるwwwwwwwwwwどうにかしないとwwwwwwwwwww
でwwwwww長すぎるwwwwwwwのでwwwww最後に来たソースwwwwwww
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% @author Zubenalt %% @copyright 2008 Zubenalt %% @doc An implementation of Grass, the grass-planting programming language. %% @reference %% See <a href="http://www.blue.sky.or.jp/grass/">Grass official home page</a> %% for more information about Grass. %% @version 0 %% @end %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -module(grass). %% -compile(export_all). -export([test/0, eval/1, parse/1,scan/1,exec/1]). %% @spec test()-> [ok] %% @doc evaluate test()-> lists:map(fun(X)-> io:format("~s~n",[element(1,X)]), eval(element(2,X)), io:format("~ndone.~n") end, [{"Calculate 1 + 1 and print the result by the number of 'w'", "wwWWwvwwwwWWWwwWwwWWWWWWwwwwWwwvwWWwwwWwwwwWwwwwwwWwwwwwwwww"}, {"Calculate (2^2)^2 and print the result by the number of 'w'", "wwWWwWWWwvwWWwwWwwwWwwwwwWwwwwwwww"}, {"Print printable ASCII characters", "wWWwWWWWwvwwWWwWWWwvwwwWWWwwWwwWWWWwvwWWwwwWWWwWWWWWwwWwwwwwWwwwWWWWWWWWwWWWWwwwWwwwWWWWWWWWWWwWWWWwwwwwwwwwwwwwwwWwwwwwwwwwwwwwwwwwWWWwwwwwwwwwwwwwwwWww"}, {"Print fib(n) by the number of 'w' from n=1 to n=12", "wwWWwwWwwvwwWWWwWWWwvwWWwWwvwvwwWWWwwvwwvwWWWwwWWwWwwwwwvwwwWWwwwWWwvwwwWWWWwwWWWWWWWWwwWWWWWwwWwwWwwwwwwwwwwwwvwwwWWWwwWwwWWWWwvwwWWwvwWWWwwWwWWWWWwwWwwwwwwWwwwWWWWWwWwwwwwwwwwwwwwwwwwwwwWWWWWwWwwwwwwwwwwwwwwwwwwwwwwwWWWWWWWWWWwwwwwwwwwwwwwwwwwwwwwwWwwwwwwwwwwwwwwwwwwwwwwwwwWWWWWWWWWWWWWWWWWWWWWWWWwwwvwwwwWWWWWwwWWWWwwwwwwwwWwwwwWWWWWWWWWWWwwwwWWWWWWWWWWWWWWwWwWwwwwwwwwwwWwwwwwwwwwWwwwwwwWwwwwwwvwWWWWWwwwwWwWwwwwwwwWwwWWwWWWWWWWWWWWWWWWWWwwwwwwwWwwwwwwwwwwwwwwwWwwwwwwwwwwwWwwww"}]). %% @spec eval(Src::string())->ok %% @doc evaluates Grass code. eval(Src)-> exec(parse(Src)). %% @spec parse(Src::string())->code() %% @doc generates internal expression from Grass code. parse(Src)-> parse_prog(scan(Src)). %% @spec scan(Src::string())->[{char(),int()}] %% @doc tokenize Grass code. scan(S)-> scan(S,[]). %% @spec exec(code())->{ok, env()} %% @doc evaluates internal expression. exec(Code)-> transform({Code,e_0(),d_0()}). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% private functions (not exported) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% @type val() = {abs, integer(), code()} | {app, integer(), integer()} %% |{prim, function()} | {char, char()} %% @type code()=[val()] %% @type f() ={code(), env()} %% @type env() =[f()] %% @type dump()=[{code(),env()}] %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% parse_app(Src)-> parse_app(Src,[]). parse_app([],Res)-> lists:reverse(Res); parse_app([{$W,N1}| [{$w,N2}|T]],Res)-> parse_app(T,[{app, N1, N2}|Res]); parse_app(_,_)-> throw({failed, {sytax_error, unknown_state}}). parse_abs([{$w,N}|T]) -> {abs, N, parse_app(T,[])}; parse_abs(_) -> throw({failed, {syntax_error, unknown_state}}). parse_prog(T)-> lists:map(fun(L)-> case hd(L) of {$w,_} -> parse_abs(L); {$W,_} -> parse_app(L) end end, split(T)). split(Src)-> split(Src,[]). split(T,Res)-> {L,R}=lists:splitwith(fun(X)-> element(1,X)=/=$v end,T), case R of [_|[]]-> throw({failed, syntax_error}); [Rh|Rt] -> case Rh of {$v,1}-> split(Rt,[L|Res]); _-> throw({failed, {syntax_error, v_duplicated}}) end; [] -> lists:reverse([L|Res]); _ -> throw({failed, sytax_error}) end. scan([],Res) -> lists:reverse(Res); scan([$w|T],[]) -> scan(T,[{$w,1}]); scan([_|T],[]) -> scan(T,[]); scan([H|T],Res) when (H=:=$w) or (H=:=$W) or (H=:=$v)-> case hd(Res) of {H,N}-> scan(T,[{H,N+1}|tl(Res)]); _-> scan(T,[{H,1}|Res]) end; scan([_|T],Res) -> scan(T,Res). %% @spec transform({C::code(),E::env(),D::dump()})->{ok, env()} transform({[], [_], []})-> ok; transform({[{abs, 1, C_}|C], E, D})-> transform({C, [{C_, E}|E], D}); transform({ [{abs,N,C_}|C], E, D}) -> transform({C, [{[{abs,N-1,C_}], E}|E ], D}); transform({[], [F|E], [{C_,E_}|D]}) -> transform({C_, [F|E_],D}); transform({[{app, M, N}|C], E, D}) -> F=lists:nth(M,E), V=lists:nth(N,E), case F of {prim, X}-> transform({C,[X(V)|E],D}); {char, _} -> transform({C,[char_eq(F,V)|E],D}); {C_, E_} -> transform({C_, [V|E_], [{C,E}|D]}) end. e_0()-> [out(),succ(),w(),in()]. d_0()-> [{[{app,1,1}],[]},{[],[]}]. out()-> {prim, fun o/1}. in()-> {prim, fun i/1}. succ()-> {prim, fun succ/1}. w()-> {char, $w}. o({char, C})-> io:format("~c",[C]), {char, C}. i(X)-> case io:get_chars('',1) of eof-> X; [C] -> {char, C} end. succ({char, C})-> {char, (C+1) rem 256}. church_true()-> {[{abs, 1, [{app, 3, 2}]}], [{[],[]}]}. church_false()-> {[{abs, 1, []}], []}. char_eq({char, C1}, {char, C2})-> case C1 of C2 -> church_true(); _-> church_false() end; char_eq(_,_) -> church_false().
草生やしなれていないから疲れる(´・ω・`)