121 lines
3.0 KiB
Erlang
121 lines
3.0 KiB
Erlang
% @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().
|