Packages
kirala_l4u
0.1.1
An embedded lisp interpreter based on the gleam implementation of MAL lisp.
Current section
Files
Jump to
Current section
Files
src/l4u@process.erl
-module(l4u@process).
-behavior(gen_server).
-compile(export_all).
-record(state, {env}).
-define(DEFAULT_TIMEOUT, infinity).
%%
%% Public API
%%
% Initializer() -> Env
new_process(Initializer) ->
case gen_server:start(?MODULE, [Initializer], []) of
{ok, Pid} -> {ok,Pid};
{error, Reason} -> {error,Reason}
end.
% WithEnv(expr,env)を返す関数を実行する
% fn() -> WithEnv(expr,env)
exec(Pid, Fn) ->
%io:format("call exec: ~p~n", [Fn]),
gen_server:call(Pid, {exec, Fn},?DEFAULT_TIMEOUT).
% Fn(Env) -> Value
% exec_native(Pid, Fn) -> Result(Value,Error)
exec_native(Pid, Fn) ->
%io:format("call exec: ~p~n", [Fn]),
gen_server:call(Pid, {native_exec, Fn},?DEFAULT_TIMEOUT).
get_env(Pid) ->
{ok,Env} = gen_server:call(Pid, get_env,?DEFAULT_TIMEOUT),
Env.
%%
%% gen_server callbacks
%%
init([Initializer]) ->
Env = Initializer(),
{ok, #state{env=Env}}.
handle_call({exec, Fn}, _From, State) ->
try
%io:format("executing: ~p~n", [Fn]),
{with_env,Expr,Env} = Fn(State#state.env),
{reply,{ok, Expr}, #state{env=Env}}
catch ECls:EMsg:EStacktrace ->
{reply, {error,EMsg}, State}
end;
handle_call({native_exec, Fn}, _From, State) ->
try
Result = Fn(State#state.env),
{reply,{ok, Result}, State}
catch ECls:EMsg:EStacktrace ->
{reply, {error,EMsg}, State}
end;
handle_call(get_env, _From, State) ->
{reply,{ok, State#state.env}, State};
handle_call(terminate, _From, State) ->
{stop, norl4u, ok, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info(Msg, State) ->
error_logger:info_msg("unexpected message: ~p~n", [Msg]),
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.