% @doc % porcelain wfc ops -module(wfc). -export_type([ sentence/0 ]). -export([ test/0, to_sentence/1, rep/1, reps/1, reps/2, add/1, mul/1 ]). test() -> reptest("(*)"), reptest("(+)"), reptest("(+ a b)"), reptest("(+ a b (* a b))"), ok. reptest(S) -> io:format("input: ~s~n", [S]), rep(S), io:format("~n", []). -type sentence() :: wfc_sentence:sentence(). -spec to_sentence(term()) -> {ok, sentence()} | {error, string()}. to_sentence(Ltr = {c, _}) -> wfc_sentence:from_ltr(Ltr); to_sentence(Word = {w, _}) -> wfc_sentence:from_word(Word); to_sentence({s, Words}) -> wfc_sentence:from_list(Words); to_sentence(Bad) -> {error, wfc_utils:str("wfc:to_sentence: cannot coerce to sentence: ~p", [Bad])}. -spec rep(string()) -> ok. % @doc read/eval/print rep(String) -> case wfc_read:expr(String) of {ok, Expr, Rest} -> case wfc_eval:eval(Expr) of {ok, Result, _NewContext} -> io:format("result: ~s~n", [wfc_pp:eval_result(Result)]), %io:format("context: ~tw~n", [NewContext]), ok; %{ok, Result, NewContext}; {error, Msg} -> io:format("~s~n", [Msg]) end, io:format("rest: ~p~n", [Rest]); {error, Message} -> io:format("~s~n", [Message]) end. -spec reps(string()) -> ok. % @doc read/eval/print loop reps(String) -> reps(String, wfc_eval_context:default()). reps(String, Ctx) -> %io:format("reps(~ts, ~tw)~n", [String, Ctx]), case wfc_read:expr(String) of {ok, Expr, Rest} -> %io:format("{ok, ~tw, ~ts}~n", [Expr, Rest]), case wfc_eval:eval(Expr, Ctx) of {ok, Result, NewContext} -> io:format("result: ~s~n", [wfc_pp:eval_result(Result)]), io:format("context: ~tw~n", [NewContext]), reps(Rest, NewContext); {error, Msg} -> io:format("~s~n", [Msg]) end, io:format("rest: ~p~n~n", [Rest]); {error, Message} -> io:format("~s~n", [Message]) end. -spec add([term()]) -> {ok, sentence()} | {error, string()}. add([Arg | Rest]) -> case to_sentence(Arg) of {ok, S} -> case add(Rest) of {ok, S2} -> io:format("S2 = ~p~n", [S2]), {ok, wfc_sentence:add(S, S2)}; Error -> Error end; Error -> Error end; add([]) -> {ok, wfc_sentence:zero()}. -spec mul([term()]) -> {ok, sentence()} | {error, string()}. mul([Arg | Rest]) -> case to_sentence(Arg) of {ok, S} -> case mul(Rest) of {ok, S2} -> {ok, wfc_sentence:mul(S, S2)}; Error -> Error end; Error -> Error end; mul([]) -> {ok, wfc_sentence:one()}. zero() -> wfc_sentence:zero(). one() -> wfc_sentence:one().