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@l4u_core.erl
-module(l4u@l4u_core).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([to_l4u_bool/1, is_true_condition/1, is_empty_value/1, is_nil_value/1, is_true_value/1, is_false_value/1, description/1, description_with_text/2, string_trim/1, tokenize/2, intern_symbol/1, intern_keyword/1, intern_symbol_or_keyword/1, parse_string/2, parse_string_block/2, parse_expr/2, unwrap/1, uneval/1, print/1, pstr/1, show/1, print_2/1, add2/2, sub2/2, mul2/2, div2/2, bif_add/2, bif_sub/2, bif_mul/2, bif_div/2, bif_mod/2, bif_and/2, bif_or/2, bif_not/2, bispform_fn/2, bispform_macro/2, bif_car/2, bif_cdr/2, bif_prn/2, bif_pr_str/2, bif_println/2, bif_readline/2, bif_list/2, bif_listp/2, bif_vec/2, bif_vector/2, bif_vectorp/2, bif_to_hash_map/2, bif_hash_map/2, bif_hash_mapp/2, bif_emptyp/2, bif_nilp/2, bif_truep/2, bif_falsep/2, bif_containsp/2, bif_atomp/2, bif_keyword/2, bif_keywordp/2, bif_stringp/2, bif_numberp/2, bif_symbol/2, bif_symbolp/2, bif_sequentialp/2, bif_fnp/2, bif_macrop/2, bif_count/2, bif_atom/2, bif_deref/2, bif_reset/2, bispform_quote/2, make_container/2, get_contents/1, bif_cons/2, bif_slurp/2, bif_tokenize/2, bif_throw/2, bif_meta/2, bif_with_meta/2, plist_to_map/2, map_to_plist/2, bif_dissoc/2, bif_get/2, bif_assoc/2, bif_keys/2, bif_vals/2, bif_gensym/2, bif_time_ms/2, bif_str/2, bif_show/2, env_get_toplevel/1, env_get/2, get_macro/2, env_set_local/3, env_add_local_scope/2, env_replace_local_scope/2, get_bif_result_value/1, env_update_global_aux/4, env_set_global/3, bif_def_custom_type/2, env_get_global_aux/2, env_get_global/2, bif_global_get/2, bif_trace/2, bif_trace_clear/2, bif_instanciate_custom_type/2, bif_custom_type_to_map/2, env_erase_global/2, bispform_erase/2, env_get_global_keys/1, global_keys/2, bif_global_keys/2, trace_set_last_expr/2, trace_set_last_funcall/2, to_simple_str/1, args_to_str/1, dict_to_str/1, indent/1, vars_to_string/1, inspect/1, describe/1, bif_inspect/2, bif_describe/2, dump_dict/2, dump_closure/2, local_scopes_to_string/2, info_to_str/1, dump_env/2, bif_inspect_env/2, repl_print/1, initialize/0, trace_closure_call/4, trace_closure_return/5, repl/2, bispform_quasiquote2/2, bispform_quasiquote_expand2/2, compare_dict/2, compare/2, is_equal/2, bif_eqp/2, compare_list/2, bif_ltp/2, bif_gtp/2, bif_lteqp/2, bif_gteqp/2, parse_list/4, parse/2, read/2, bif_read_string/2, bif_read/2, eval_contents/3, eval/3, eval_expr/2, eval_funcall_args/2, bispform_def/2, bispform_let/2, bispform_defmacro/2, bif_progn/2, bispform_if/2, quasiquote_/2, bispform_quasiquote/2, bispform_quasiquote_expand/2, bif_eval/2, apply/3, apply_macro/2, macroexpand/2, macroexpand_all/2, bispform_macroexpand/2, bispform_macroexpand_all/2, bif_apply/2, bispform_try/2, rep/2, bif_load_file/2, generate_new_env/3, make_new_l4u_core_env/3, main/0]).
-export_type([scope_type/0]).
-type scope_type() :: scope_type_overwrite_local |
scope_type_simple_scopes |
scope_type_opt_scopes.
-spec to_l4u_bool(boolean()) -> l4u@l4u_type:expr().
to_l4u_bool(Flag) ->
case Flag of
true ->
true;
false ->
false
end.
-spec is_true_condition(l4u@l4u_type:expr()) -> boolean().
is_true_condition(E) ->
case E of
false ->
false;
nil ->
false;
undefined ->
false;
_ ->
true
end.
-spec is_empty_value(l4u@l4u_type:expr()) -> boolean().
is_empty_value(Val) ->
case Val of
undefined ->
true;
nil ->
true;
{list, []} ->
true;
{vector, []} ->
true;
{dict, []} ->
true;
{string, <<""/utf8>>} ->
true;
_ ->
false
end.
-spec is_nil_value(l4u@l4u_type:expr()) -> boolean().
is_nil_value(Val) ->
case Val of
nil ->
true;
_ ->
false
end.
-spec is_true_value(l4u@l4u_type:expr()) -> boolean().
is_true_value(Val) ->
case Val of
true ->
true;
_ ->
false
end.
-spec is_false_value(l4u@l4u_type:expr()) -> boolean().
is_false_value(Val) ->
case Val of
false ->
true;
_ ->
false
end.
-spec description(binary()) -> l4u@l4u_type:description().
description(Name) ->
{description, Name, <<""/utf8>>}.
-spec description_with_text(binary(), binary()) -> l4u@l4u_type:description().
description_with_text(Name, Text) ->
{description, Name, Text}.
-spec skip_line_comment(binary()) -> binary().
skip_line_comment(Source) ->
case gleam@string:pop_grapheme(Source) of
{ok, {<<""/utf8>>, Rest}} ->
Rest;
{ok, {<<"\n"/utf8>>, Rest@1}} ->
Rest@1;
{ok, {_, Rest@2}} ->
skip_line_comment(Rest@2);
{error, _} ->
<<""/utf8>>
end.
-spec skip_block_comment(binary()) -> binary().
skip_block_comment(Source) ->
case Source of
<<"*/"/utf8, Rest/binary>> ->
Rest;
_ ->
case gleam@string:pop_grapheme(Source) of
{ok, {_, Rest@1}} ->
skip_block_comment(Rest@1);
{error, _} ->
<<""/utf8>>
end
end.
-spec remove_comment_from_source(binary(), binary()) -> binary().
remove_comment_from_source(Source, Trimmed) ->
case Source of
<<"#!/"/utf8, Rest/binary>> ->
remove_comment_from_source(skip_line_comment(Rest), Trimmed);
<<";"/utf8, Rest@1/binary>> ->
remove_comment_from_source(skip_line_comment(Rest@1), Trimmed);
<<"/*"/utf8, Rest@2/binary>> ->
remove_comment_from_source(skip_block_comment(Rest@2), Trimmed);
<<""/utf8>> ->
Trimmed;
_ ->
case gleam@string:pop_grapheme(Source) of
{ok, {Char, Rest@3}} ->
remove_comment_from_source(
Rest@3,
<<Trimmed/binary, Char/binary>>
);
_ ->
Trimmed
end
end.
-spec remove_comment(binary()) -> binary().
remove_comment(Source) ->
case Source of
<<"#!/"/utf8, Rest/binary>> ->
<<""/utf8>>;
<<";"/utf8, Rest@1/binary>> ->
<<""/utf8>>;
<<""/utf8>> ->
<<""/utf8>>;
_ ->
Source
end.
-spec string_trim(binary()) -> binary().
string_trim(Source) ->
{Char, Rest} = begin
_pipe = gleam@string:pop_grapheme(Source),
gleam@result:unwrap(_pipe, {<<""/utf8>>, <<""/utf8>>})
end,
case Char of
<<""/utf8>> ->
<<""/utf8>>;
<<" "/utf8>> ->
string_trim(Rest);
<<"\r"/utf8>> ->
string_trim(Rest);
<<"\n"/utf8>> ->
string_trim(Rest);
<<"\t"/utf8>> ->
string_trim(Rest);
_ ->
Source
end.
-spec tokenize_1(binary(), l4u@l4u_type:env()) -> list(binary()).
tokenize_1(Src, Env) ->
Tokens = begin
_pipe = gleam@regex:split(
l4u@sys_bridge_ffi:process_dict_get(
erlang:element(3, Env),
<<"*regex"/utf8>>
),
Src
),
_pipe@3 = gleam@list:map(_pipe, fun(Str) -> _pipe@1 = Str,
_pipe@2 = gleam@string:trim(_pipe@1),
remove_comment(_pipe@2) end),
gleam@list:filter(_pipe@3, fun(X) -> X /= <<""/utf8>> end)
end.
-spec tokenize(binary(), l4u@l4u_type:env()) -> list(binary()).
tokenize(Src, Env) ->
Lines = begin
_pipe = l4u@l4u_util:split_multiline_string(Src),
_pipe@1 = gleam@list:map(_pipe, fun(Line) -> case Line of
<<"\"\"\""/utf8, _/binary>> ->
[Line];
_ ->
tokenize_1(Line, Env)
end end),
gleam@list:flatten(_pipe@1)
end,
Lines.
-spec intern_symbol(binary()) -> l4u@l4u_type:expr().
intern_symbol(Str) ->
case Str of
<<"undefined"/utf8>> ->
undefined;
<<"nil"/utf8>> ->
nil;
<<"true"/utf8>> ->
true;
<<"false"/utf8>> ->
false;
_ ->
New_key = erlang:binary_to_atom(Str),
case persistent_term:get(New_key, undefined) of
undefined ->
New_symbol = {symbol, Str},
persistent_term:put(New_key, New_symbol),
New_symbol;
Interened_symbol ->
Interened_symbol
end
end.
-spec intern_keyword(binary()) -> l4u@l4u_type:expr().
intern_keyword(Str) ->
case gleam@string:starts_with(Str, <<":"/utf8>>) of
true ->
{keyword, gleam@string:drop_left(Str, 1)};
_ ->
{keyword, Str}
end.
-spec intern_symbol_or_keyword(binary()) -> l4u@l4u_type:expr().
intern_symbol_or_keyword(Str) ->
case gleam@string:pop_grapheme(Str) of
{ok, {<<":"/utf8>>, Rest}} ->
intern_keyword(Rest);
{ok, {<<"$"/utf8>>, Rest@1}} ->
{ex_var, <<"external"/utf8>>, Rest@1};
_ ->
intern_symbol(Str)
end.
-spec parse_string(binary(), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
parse_string(Str, Env) ->
_assert_subject = {ok, gleam@string:ends_with(Str, <<"\""/utf8>>)},
{ok, true} = case _assert_subject of
{ok, true} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"parse_string"/utf8>>,
line => 396})
end,
{string,
l4u@sys_bridge_ffi:unescape_binary_string(
gleam@string:slice(Str, 0, gleam@string:length(Str) - 1)
)}.
-spec parse_string_block(binary(), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
parse_string_block(Str, Env) ->
_assert_subject = {ok, gleam@string:ends_with(Str, <<"\"\"\""/utf8>>)},
{ok, true} = case _assert_subject of
{ok, true} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"parse_string_block"/utf8>>,
line => 402})
end,
{string, gleam@string:slice(Str, 0, gleam@string:length(Str) - 3)}.
-spec parse_expr(binary(), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
parse_expr(Token, Env) ->
case Token of
<<"\"\"\""/utf8, Str/binary>> ->
parse_string_block(Str, Env);
<<"\""/utf8, Str@1/binary>> ->
parse_string(Str@1, Env);
_ ->
case gleam@int:parse(Token) of
{ok, Value} ->
{int, Value};
{error, _} ->
case gleam@float:parse(Token) of
{ok, Value@1} ->
{float, Value@1};
{error, _} ->
intern_symbol_or_keyword(Token)
end
end
end.
-spec bind_args(
gleam@dict:dict(binary(), l4u@l4u_type:expr()),
list(binary()),
list(l4u@l4u_type:expr())
) -> gleam@dict:dict(binary(), l4u@l4u_type:expr()).
bind_args(Bindings, Params, Args) ->
case {Params, Args} of
{[], []} ->
Bindings;
{[<<"&"/utf8>>, Sym_rest], Rest_args} ->
gleam@dict:insert(Bindings, Sym_rest, {list, Rest_args});
{[Param | Rest_params], [Arg | Rest_args@1]} ->
bind_args(
gleam@dict:insert(Bindings, Param, Arg),
Rest_params,
Rest_args@1
);
{_, _} ->
l4u@sys_bridge_ffi:throw_err(<<"unhandable args"/utf8>>),
Bindings
end.
-spec unwrap(l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
unwrap(Expr) ->
case Expr of
{with_meta, E, _} ->
E;
_ ->
Expr
end.
-spec uneval(l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
uneval(Expr) ->
case Expr of
{vector, Contents} ->
{list, Contents};
{list, Contents@1} ->
{list, Contents@1};
{dict, Contents@2} ->
{list, Contents@2};
_ ->
Expr
end.
-spec generate_local_env__overwrite_local(
binary(),
l4u@l4u_type:env(),
gleam@dict:dict(binary(), l4u@l4u_type:expr()),
gleam@dict:dict(binary(), l4u@l4u_type:expr())
) -> l4u@l4u_type:env().
generate_local_env__overwrite_local(Name, Env, Bindings, A_bindings) ->
erlang:setelement(
5,
erlang:setelement(
4,
erlang:setelement(
2,
Env,
{info, Name, erlang:element(3, erlang:element(2, Env)) + 1}
),
gleam@dict:merge(erlang:element(4, Env), Bindings)
),
gleam@dict:merge(erlang:element(5, Env), A_bindings)
).
-spec generate_local_env__opt_scopes(
binary(),
l4u@l4u_type:env(),
gleam@dict:dict(binary(), l4u@l4u_type:expr()),
gleam@dict:dict(binary(), l4u@l4u_type:expr())
) -> l4u@l4u_type:env().
generate_local_env__opt_scopes(Name, Env, Bindings, A_bindings) ->
case maps:size(Bindings) of
0 ->
Env;
_ ->
erlang:setelement(
6,
erlang:setelement(
5,
erlang:setelement(
4,
erlang:setelement(
2,
Env,
{info,
Name,
erlang:element(3, erlang:element(2, Env)) + 1}
),
Bindings
),
gleam@dict:merge(erlang:element(5, Env), A_bindings)
),
[{scope, erlang:element(4, Env)} | erlang:element(6, Env)]
)
end.
-spec generate_local_env__simple_scope(
binary(),
l4u@l4u_type:env(),
gleam@dict:dict(binary(), l4u@l4u_type:expr()),
gleam@dict:dict(binary(), l4u@l4u_type:expr())
) -> l4u@l4u_type:env().
generate_local_env__simple_scope(Name, Env, Bindings, A_bindings) ->
erlang:setelement(
6,
erlang:setelement(
5,
erlang:setelement(
4,
erlang:setelement(
2,
Env,
{info, Name, erlang:element(3, erlang:element(2, Env)) + 1}
),
Bindings
),
gleam@dict:merge(erlang:element(5, Env), A_bindings)
),
[{scope, erlang:element(4, Env)} | erlang:element(6, Env)]
).
-spec print(l4u@l4u_type:expr()) -> binary().
print(Expr) ->
case Expr of
{with_env, Expr@1, _} ->
print(Expr@1);
undefined ->
<<"undefined"/utf8>>;
nil ->
<<"nil"/utf8>>;
true ->
<<"true"/utf8>>;
false ->
<<"false"/utf8>>;
{float, Val} ->
gleam@float:to_string(Val);
{int, Val@1} ->
gleam@int:to_string(Val@1);
{string, Val@2} ->
<<<<"\""/utf8,
(l4u@sys_bridge_ffi:escape_binary_string(Val@2))/binary>>/binary,
"\""/utf8>>;
{symbol, Val@3} ->
Val@3;
{keyword, Val@4} ->
<<":"/utf8, Val@4/binary>>;
delimiter ->
<<""/utf8>>;
{list, Val@5} ->
<<<<"("/utf8,
(gleam@string:join(
gleam@list:map(Val@5, fun(Expr@2) -> print(Expr@2) end),
<<" "/utf8>>
))/binary>>/binary,
")"/utf8>>;
{vector, Val@6} ->
<<<<"["/utf8,
(gleam@string:join(
gleam@list:map(Val@6, fun(Expr@3) -> print(Expr@3) end),
<<" "/utf8>>
))/binary>>/binary,
"]"/utf8>>;
{dict, Val@7} ->
<<<<"{"/utf8,
(gleam@string:join(
gleam@list:map(Val@7, fun(Expr@4) -> print(Expr@4) end),
<<" "/utf8>>
))/binary>>/binary,
"}"/utf8>>;
{closure, Desc, Params, Body, Closure_env} ->
Body@1 = gleam@list:map(Body, fun(E) -> print(E) end),
<<<<<<<<"(fn* ("/utf8,
(gleam@string:join(Params, <<" "/utf8>>))/binary>>/binary,
") "/utf8>>/binary,
(gleam@string:join(Body@1, <<" "/utf8>>))/binary>>/binary,
")"/utf8>>;
{atom, Ref} ->
<<<<"(atom "/utf8, (print(l4u@sys_bridge_ffi:deref(Ref)))/binary>>/binary,
")"/utf8>>;
{bif, Desc@1, _} ->
erlang:element(2, Desc@1);
{bispform, Desc@2, _} ->
<<<<"#<bispform:"/utf8, (erlang:element(2, Desc@2))/binary>>/binary,
">"/utf8>>;
{with_meta, Expr@5, Meta} ->
print(Expr@5);
{macro, _, _, _, _} ->
<<"#<macro>"/utf8>>;
{custom_type_def, Name, Expr@6} ->
<<<<<<<<"(custom-type-def "/utf8, Name/binary>>/binary, " "/utf8>>/binary,
(print(Expr@6))/binary>>/binary,
">"/utf8>>;
{custom_type, Name@1, Expr@7} ->
<<<<<<<<"("/utf8, Name@1/binary>>/binary, " "/utf8>>/binary,
(print(Expr@7))/binary>>/binary,
" )"/utf8>>;
_ ->
l4u@sys_bridge_ffi:external_form(Expr)
end.
-spec pstr(l4u@l4u_type:expr()) -> binary().
pstr(Expr) ->
case Expr of
{with_env, Expr@1, _} ->
pstr(Expr@1);
undefined ->
<<"undefined"/utf8>>;
nil ->
<<"nil"/utf8>>;
true ->
<<"true"/utf8>>;
false ->
<<"false"/utf8>>;
{float, Val} ->
gleam@float:to_string(Val);
{int, Val@1} ->
gleam@int:to_string(Val@1);
{string, Val@2} ->
Val@2;
{symbol, Val@3} ->
Val@3;
{keyword, Val@4} ->
Val@4;
delimiter ->
<<""/utf8>>;
{list, Val@5} ->
gleam@string:join(
gleam@list:map(Val@5, fun(Expr@2) -> pstr(Expr@2) end),
<<" "/utf8>>
);
{vector, Val@6} ->
gleam@string:join(
gleam@list:map(Val@6, fun(Expr@3) -> pstr(Expr@3) end),
<<" "/utf8>>
);
{dict, Val@7} ->
gleam@string:join(
gleam@list:map(Val@7, fun(Expr@4) -> pstr(Expr@4) end),
<<" "/utf8>>
);
{closure, Desc, Params, Body, Closure_env} ->
Body@1 = gleam@list:map(Body, fun(E) -> print(E) end),
<<<<<<<<"(fn* ("/utf8,
(gleam@string:join(Params, <<" "/utf8>>))/binary>>/binary,
") "/utf8>>/binary,
(gleam@string:join(Body@1, <<" "/utf8>>))/binary>>/binary,
")"/utf8>>;
{atom, _} ->
<<"#<atom>"/utf8>>;
{bif, Desc@1, _} ->
erlang:element(2, Desc@1);
{bispform, Desc@2, _} ->
<<<<"#<bispform:"/utf8, (erlang:element(2, Desc@2))/binary>>/binary,
">"/utf8>>;
{with_meta, Expr@5, Meta} ->
pstr(Expr@5);
{macro, _, _, _, _} ->
<<"#<macro>"/utf8>>;
{custom_type_def, Name, Expr@6} ->
<<<<<<<<"(custom-type-def "/utf8, Name/binary>>/binary, " "/utf8>>/binary,
(print(Expr@6))/binary>>/binary,
">"/utf8>>;
{custom_type, Name@1, Expr@7} ->
<<<<<<<<"("/utf8, Name@1/binary>>/binary, " "/utf8>>/binary,
(print(Expr@7))/binary>>/binary,
" )"/utf8>>;
_ ->
l4u@sys_bridge_ffi:external_form(Expr)
end.
-spec show(l4u@l4u_type:expr()) -> binary().
show(Expr) ->
case Expr of
{with_env, Expr@1, _} ->
show(Expr@1);
undefined ->
<<"undefined"/utf8>>;
nil ->
<<"nil"/utf8>>;
true ->
<<"true"/utf8>>;
false ->
<<"false"/utf8>>;
{float, Val} ->
gleam@float:to_string(Val);
{int, Val@1} ->
gleam@int:to_string(Val@1);
{string, Val@2} ->
Val@2;
{symbol, Val@3} ->
Val@3;
{keyword, Val@4} ->
<<":"/utf8, Val@4/binary>>;
delimiter ->
<<""/utf8>>;
{list, Val@5} ->
<<<<"("/utf8,
(gleam@string:join(
gleam@list:map(Val@5, fun(Expr@2) -> show(Expr@2) end),
<<" "/utf8>>
))/binary>>/binary,
")"/utf8>>;
{vector, Val@6} ->
<<<<"["/utf8,
(gleam@string:join(
gleam@list:map(Val@6, fun(Expr@3) -> show(Expr@3) end),
<<" "/utf8>>
))/binary>>/binary,
"]"/utf8>>;
{dict, Val@7} ->
<<<<"{"/utf8,
(gleam@string:join(
gleam@list:map(Val@7, fun(Expr@4) -> show(Expr@4) end),
<<" "/utf8>>
))/binary>>/binary,
"}"/utf8>>;
{closure, Desc, Params, Body, Closure_env} ->
Body@1 = gleam@list:map(Body, fun(E) -> print(E) end),
<<<<<<<<"(fn* ("/utf8,
(gleam@string:join(Params, <<" "/utf8>>))/binary>>/binary,
") "/utf8>>/binary,
(gleam@string:join(Body@1, <<" "/utf8>>))/binary>>/binary,
")"/utf8>>;
{atom, _} ->
<<"#<atom>"/utf8>>;
{bif, Desc@1, _} ->
erlang:element(2, Desc@1);
{bispform, Desc@2, _} ->
<<<<"#<bispform:"/utf8, (erlang:element(2, Desc@2))/binary>>/binary,
">"/utf8>>;
{with_meta, Expr@5, Meta} ->
show(Expr@5);
{macro, _, _, _, _} ->
<<"#<macro>"/utf8>>;
{custom_type_def, Name, Expr@6} ->
<<<<<<<<"(custom-type-def "/utf8, Name/binary>>/binary, " "/utf8>>/binary,
(print(Expr@6))/binary>>/binary,
">"/utf8>>;
{custom_type, Name@1, Expr@7} ->
<<<<<<<<"("/utf8, Name@1/binary>>/binary, " "/utf8>>/binary,
(print(Expr@7))/binary>>/binary,
" )"/utf8>>;
_ ->
l4u@sys_bridge_ffi:external_form(Expr)
end.
-spec print_2(l4u@l4u_type:expr()) -> binary().
print_2(Expr) ->
case Expr of
{with_env, Expr@1, _} ->
print(Expr@1);
undefined ->
<<"undefined"/utf8>>;
nil ->
<<"nil"/utf8>>;
true ->
<<"true"/utf8>>;
false ->
<<"false"/utf8>>;
{float, Val} ->
gleam@float:to_string(Val);
{int, Val@1} ->
gleam@int:to_string(Val@1);
{string, Val@2} ->
Val@2;
{symbol, Val@3} ->
Val@3;
{keyword, Val@4} ->
<<":"/utf8, Val@4/binary>>;
delimiter ->
<<""/utf8>>;
{list, Val@5} ->
<<<<"("/utf8,
(gleam@string:join(
gleam@list:map(Val@5, fun(Expr@2) -> print(Expr@2) end),
<<", "/utf8>>
))/binary>>/binary,
")"/utf8>>;
{vector, Val@6} ->
<<<<"["/utf8,
(gleam@string:join(
gleam@list:map(Val@6, fun(Expr@3) -> print(Expr@3) end),
<<", "/utf8>>
))/binary>>/binary,
"]"/utf8>>;
{dict, Val@7} ->
<<<<"{"/utf8,
(gleam@string:join(
gleam@list:map(Val@7, fun(Expr@4) -> print(Expr@4) end),
<<", "/utf8>>
))/binary>>/binary,
"}"/utf8>>;
{closure, _, _, _, _} ->
<<"#<closure>"/utf8>>;
{atom, _} ->
<<"#<atom>"/utf8>>;
{bif, Desc, _} ->
<<<<"#<bif:"/utf8, (erlang:element(2, Desc))/binary>>/binary,
">"/utf8>>;
{bispform, Desc@1, _} ->
<<<<"#<bispform:"/utf8, (erlang:element(2, Desc@1))/binary>>/binary,
">"/utf8>>;
{with_meta, Expr@5, Meta} ->
print(Expr@5);
{macro, _, _, _, _} ->
<<"#<macro>"/utf8>>;
{custom_type_def, Name, Expr@6} ->
<<<<<<<<"(custom-type-def "/utf8, Name/binary>>/binary, " "/utf8>>/binary,
(print(Expr@6))/binary>>/binary,
">"/utf8>>;
{custom_type, Name@1, Expr@7} ->
<<<<<<<<"("/utf8, Name@1/binary>>/binary, " "/utf8>>/binary,
(print(Expr@7))/binary>>/binary,
" )"/utf8>>;
_ ->
l4u@sys_bridge_ffi:internal_form(Expr)
end.
-spec add2(l4u@l4u_type:expr(), l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
add2(X, Y) ->
case {X, Y} of
{{int, X@1}, {int, Y@1}} ->
{int, X@1 + Y@1};
{{float, X@2}, {float, Y@2}} ->
{float, X@2 + Y@2};
{{int, X@3}, {float, Y@3}} ->
{float, gleam@int:to_float(X@3) + Y@3};
{{float, X@4}, {int, Y@4}} ->
{float, X@4 + gleam@int:to_float(Y@4)};
{_, _} ->
undefined
end.
-spec sub2(l4u@l4u_type:expr(), l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
sub2(X, Y) ->
case {X, Y} of
{{int, X@1}, {int, Y@1}} ->
{int, X@1 - Y@1};
{{float, X@2}, {float, Y@2}} ->
{float, X@2 - Y@2};
{{int, X@3}, {float, Y@3}} ->
{float, gleam@int:to_float(X@3) - Y@3};
{{float, X@4}, {int, Y@4}} ->
{float, X@4 + gleam@int:to_float(Y@4)};
{_, _} ->
undefined
end.
-spec mul2(l4u@l4u_type:expr(), l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
mul2(X, Y) ->
case {X, Y} of
{{int, X@1}, {int, Y@1}} ->
{int, X@1 * Y@1};
{{float, X@2}, {float, Y@2}} ->
{float, X@2 * Y@2};
{{int, X@3}, {float, Y@3}} ->
{float, gleam@int:to_float(X@3) * Y@3};
{{float, X@4}, {int, Y@4}} ->
{float, X@4 * gleam@int:to_float(Y@4)};
{_, _} ->
undefined
end.
-spec div2(l4u@l4u_type:expr(), l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
div2(X, Y) ->
case {X, Y} of
{{int, X@1}, {int, Y@1}} ->
{int, case Y@1 of
0 -> 0;
Gleam@denominator -> X@1 div Gleam@denominator
end};
{{float, X@2}, {float, Y@2}} ->
{float, case Y@2 of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator@1 -> X@2 / Gleam@denominator@1
end};
{{int, X@3}, {float, Y@3}} ->
{float, case Y@3 of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator@2 -> gleam@int:to_float(X@3) / Gleam@denominator@2
end};
{{float, X@4}, {int, Y@4}} ->
{float, case gleam@int:to_float(Y@4) of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator@3 -> X@4 / Gleam@denominator@3
end};
{_, _} ->
undefined
end.
-spec bif_add(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_add(Exprs, Env) ->
{with_env, gleam@list:fold(Exprs, {int, 0}, fun add2/2), Env}.
-spec bif_sub(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_sub(Exprs, Env) ->
[X | Xs] = case Exprs of
[_ | _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_sub"/utf8>>,
line => 1207})
end,
{with_env, gleam@list:fold(Xs, X, fun sub2/2), Env}.
-spec bif_mul(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_mul(Exprs, Env) ->
[X | Xs] = case Exprs of
[_ | _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_mul"/utf8>>,
line => 1212})
end,
{with_env, gleam@list:fold(Xs, X, fun mul2/2), Env}.
-spec bif_div(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_div(Exprs, Env) ->
[X | Xs] = case Exprs of
[_ | _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_div"/utf8>>,
line => 1217})
end,
{with_env, gleam@list:fold(Xs, X, fun div2/2), Env}.
-spec bif_mod(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_mod(Exprs, Env) ->
[{int, X}, {int, Y}] = case Exprs of
[{int, _}, {int, _}] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_mod"/utf8>>,
line => 1222})
end,
{with_env, {int, case Y of
0 -> 0;
Gleam@denominator -> X rem Gleam@denominator
end}, Env}.
-spec bif_and(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_and(Exprs, Env) ->
case Exprs of
[] ->
{with_env, true, Env};
[X | Xs] ->
case is_true_condition(X) of
true ->
bif_and(Xs, Env);
false ->
{with_env, false, Env}
end
end.
-spec bif_or(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_or(Exprs, Env) ->
case Exprs of
[] ->
{with_env, false, Env};
[X | Xs] ->
case is_true_condition(X) of
false ->
bif_or(Xs, Env);
true ->
{with_env, true, Env}
end
end.
-spec bif_not(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_not(Exprs, Env) ->
[X] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_not"/utf8>>,
line => 1402})
end,
case is_true_condition(X) of
true ->
{with_env, false, Env};
false ->
{with_env, true, Env}
end.
-spec separate_property(list(l4u@l4u_type:expr()), binary()) -> {binary(),
list(l4u@l4u_type:expr())}.
separate_property(Body, Property_name) ->
case Body of
[{keyword, Name}, {string, Property_value} | Rest] when Property_name =:= Name ->
{Property_value, Rest};
_ ->
{<<""/utf8>>, Body}
end.
-spec bispform_fn(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_fn(Exprs, Env) ->
[First | Body] = case Exprs of
[_ | _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_fn"/utf8>>,
line => 1540})
end,
_assert_subject = uneval(First),
{list, Params} = case _assert_subject of
{list, _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_fn"/utf8>>,
line => 1541})
end,
{Name, Body@1} = separate_property(Body, <<"name"/utf8>>),
{Description_text, Body@2} = separate_property(
Body@1,
<<"description"/utf8>>
),
Name@1 = case Name of
<<""/utf8>> ->
l4u@sys_bridge_ffi:unique_str();
_ ->
Name
end,
Closure = {closure,
description_with_text(Name@1, Description_text),
gleam@list:map(Params, fun(E) -> case E of
{symbol, Sym} ->
Sym;
_ ->
l4u@sys_bridge_ffi:throw_err(
<<"invalid parameter"/utf8>>
),
<<""/utf8>>
end end),
Body@2,
Env},
{with_env, Closure, Env}.
-spec closure_to_macro(l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
closure_to_macro(Closure) ->
{closure, Name, Params, Body, Closure_env} = case Closure of
{closure, _, _, _, _} -> Closure;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"closure_to_macro"/utf8>>,
line => 1576})
end,
{macro, Name, Params, Body, Closure_env}.
-spec bispform_macro(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_macro(Exprs, Env) ->
_assert_subject = bispform_fn(Exprs, Env),
{with_env, Closure, New_env} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_macro"/utf8>>,
line => 1581})
end,
Macroval = closure_to_macro(Closure),
{with_env, Macroval, Env}.
-spec bif_car(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_car(Exprs, Env) ->
case Exprs of
[{list, Contents}] ->
case Contents of
[Car | Cdr] ->
{with_env, Car, Env};
[] ->
{with_env, nil, Env}
end;
[{vector, Contents}] ->
case Contents of
[Car | Cdr] ->
{with_env, Car, Env};
[] ->
{with_env, nil, Env}
end;
[{dict, Contents}] ->
case Contents of
[Car | Cdr] ->
{with_env, Car, Env};
[] ->
{with_env, nil, Env}
end;
_ ->
{with_env, nil, Env}
end.
-spec bif_cdr(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_cdr(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_cdr"/utf8>>,
line => 1628})
end,
case Expr of
{list, Contents} ->
case Contents of
[_ | Cdr] ->
{with_env, {list, Cdr}, Env};
[] ->
{with_env, {list, []}, Env}
end;
{vector, Contents} ->
case Contents of
[_ | Cdr] ->
{with_env, {list, Cdr}, Env};
[] ->
{with_env, {list, []}, Env}
end;
{dict, Contents} ->
case Contents of
[_ | Cdr] ->
{with_env, {list, Cdr}, Env};
[] ->
{with_env, {list, []}, Env}
end;
_ ->
{with_env, {list, []}, Env}
end.
-spec bif_prn(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_prn(Exprs, Env) ->
Str = gleam@string:join(
gleam@list:map(Exprs, fun(Expr) -> print(Expr) end),
<<" "/utf8>>
),
l4u@sys_bridge_ffi:console_writeln(Str),
{with_env, nil, Env}.
-spec bif_pr_str(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_pr_str(Exprs, Env) ->
Str = gleam@string:join(
gleam@list:map(Exprs, fun(Expr) -> print(Expr) end),
<<" "/utf8>>
),
l4u@sys_bridge_ffi:console_writeln(
<<<<"\""/utf8, (l4u@sys_bridge_ffi:escape_binary_string(Str))/binary>>/binary,
"\""/utf8>>
),
{with_env, {string, Str}, Env}.
-spec bif_println(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_println(Exprs, Env) ->
Str = gleam@string:join(
gleam@list:map(Exprs, fun(Expr) -> show(Expr) end),
<<" "/utf8>>
),
l4u@sys_bridge_ffi:console_writeln(Str),
{with_env, nil, Env}.
-spec bif_readline(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_readline(Exprs, Env) ->
Prompt@1 = case Exprs of
[Prompt] ->
show(uneval(Prompt));
_ ->
<<""/utf8>>
end,
Line = l4u@sys_bridge_ffi:console_readline(Prompt@1),
{with_env, {string, Line}, Env}.
-spec bif_list(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_list(Exprs, Env) ->
{with_env, {list, Exprs}, Env}.
-spec bif_listp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_listp(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_listp"/utf8>>,
line => 1743})
end,
Expr@1 = unwrap(Expr),
case Expr@1 of
{list, _} ->
{with_env, true, Env};
_ ->
{with_env, false, Env}
end.
-spec bif_vec(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_vec(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_vec"/utf8>>,
line => 1752})
end,
Expr@1 = unwrap(Expr),
_assert_subject = uneval(Expr@1),
{list, Contents} = case _assert_subject of
{list, _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_vec"/utf8>>,
line => 1754})
end,
{with_env, {vector, Contents}, Env}.
-spec bif_vector(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_vector(Exprs, Env) ->
{with_env, {vector, Exprs}, Env}.
-spec bif_vectorp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_vectorp(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_vectorp"/utf8>>,
line => 1763})
end,
Expr@1 = unwrap(Expr),
case Expr@1 of
{vector, _} ->
{with_env, true, Env};
_ ->
{with_env, false, Env}
end.
-spec bif_to_hash_map(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_to_hash_map(Exprs, Env) ->
[{list, Contents}] = case Exprs of
[{list, _}] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_to_hash_map"/utf8>>,
line => 1773})
end,
{with_env, {dict, Contents}, Env}.
-spec bif_hash_map(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_hash_map(Exprs, Env) ->
{with_env, {dict, Exprs}, Env}.
-spec bif_hash_mapp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_hash_mapp(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_hash_mapp"/utf8>>,
line => 1783})
end,
Expr@1 = unwrap(Expr),
case Expr@1 of
{dict, _} ->
{with_env, true, Env};
_ ->
{with_env, false, Env}
end.
-spec bif_emptyp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_emptyp(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_emptyp"/utf8>>,
line => 1792})
end,
Expr@1 = unwrap(Expr),
{with_env, to_l4u_bool(is_empty_value(Expr@1)), Env}.
-spec bif_nilp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_nilp(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_nilp"/utf8>>,
line => 1798})
end,
Expr@1 = unwrap(Expr),
{with_env, to_l4u_bool(is_nil_value(Expr@1)), Env}.
-spec bif_truep(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_truep(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_truep"/utf8>>,
line => 1804})
end,
Expr@1 = unwrap(Expr),
{with_env, to_l4u_bool(is_true_value(Expr@1)), Env}.
-spec bif_falsep(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_falsep(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_falsep"/utf8>>,
line => 1810})
end,
Expr@1 = unwrap(Expr),
{with_env, to_l4u_bool(not is_true_value(Expr@1)), Env}.
-spec bif_containsp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_containsp(Exprs, Env) ->
[Container, Value] = case Exprs of
[_, _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_containsp"/utf8>>,
line => 1816})
end,
case {Container, Value} of
{{list, Contents}, _} ->
{with_env, to_l4u_bool(gleam@list:contains(Contents, Value)), Env};
{{dict, Contents@1}, _} ->
{with_env, to_l4u_bool(gleam@list:contains(Contents@1, Value)), Env};
{{string, Contents@2}, {string, Value@1}} ->
{with_env,
to_l4u_bool(gleam_stdlib:contains_string(Contents@2, Value@1)),
Env};
{_, _} ->
{with_env, false, Env}
end.
-spec bif_atomp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_atomp(Exprs, Env) ->
case Exprs of
[{atom, _} | Rest] ->
{with_env, true, Env};
_ ->
{with_env, false, Env}
end.
-spec bif_keyword(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_keyword(Exprs, Env) ->
case Exprs of
[{keyword, _} = Keyword] ->
{with_env, Keyword, Env};
[{string, Str} = Keyword@1] ->
{with_env, intern_keyword(Str), Env};
_ ->
l4u@sys_bridge_ffi:throw_err(<<"invalid keyword"/utf8>>),
undefined
end.
-spec bif_keywordp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_keywordp(Exprs, Env) ->
case Exprs of
[{keyword, _} | _] ->
{with_env, true, Env};
_ ->
{with_env, false, Env}
end.
-spec bif_stringp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_stringp(Exprs, Env) ->
case Exprs of
[{string, _} | _] ->
{with_env, true, Env};
_ ->
{with_env, false, Env}
end.
-spec bif_numberp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_numberp(Exprs, Env) ->
case Exprs of
[{int, _} | _] ->
{with_env, true, Env};
[{float, _} | _] ->
{with_env, true, Env};
_ ->
{with_env, false, Env}
end.
-spec bif_symbol(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_symbol(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_symbol"/utf8>>,
line => 1870})
end,
_assert_subject = uneval(Expr),
{string, Str} = case _assert_subject of
{string, _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_symbol"/utf8>>,
line => 1871})
end,
{with_env, {symbol, Str}, Env}.
-spec bif_symbolp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_symbolp(Exprs, Env) ->
case Exprs of
[{symbol, _} | _] ->
{with_env, true, Env};
_ ->
{with_env, false, Env}
end.
-spec bif_sequentialp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_sequentialp(Exprs, Env) ->
case Exprs of
[{list, _} | _] ->
{with_env, true, Env};
[{vector, _} | _] ->
{with_env, true, Env};
_ ->
{with_env, false, Env}
end.
-spec bif_fnp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_fnp(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_fnp"/utf8>>,
line => 1890})
end,
Expr@1 = unwrap(Expr),
Flag = case Expr@1 of
{bif, _, _} ->
true;
{closure, _, _, _, _} ->
true;
_ ->
false
end,
{with_env, Flag, Env}.
-spec bif_macrop(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_macrop(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_macrop"/utf8>>,
line => 1901})
end,
Expr@1 = unwrap(Expr),
Flag = case Expr@1 of
{macro, _, _, _, _} ->
true;
_ ->
false
end,
{with_env, Flag, Env}.
-spec bif_count(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_count(Exprs, Env) ->
case Exprs of
[{list, Contents}] ->
{with_env, {int, gleam@list:length(Contents)}, Env};
[{vector, Contents}] ->
{with_env, {int, gleam@list:length(Contents)}, Env};
[{dict, Contents}] ->
{with_env, {int, gleam@list:length(Contents)}, Env};
_ ->
{with_env, {int, 0}, Env}
end.
-spec bif_atom(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_atom(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_atom"/utf8>>,
line => 1921})
end,
{with_env, {atom, l4u@sys_bridge_ffi:make_ref(Expr)}, Env}.
-spec bif_deref(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_deref(Exprs, Env) ->
[{atom, Ref}] = case Exprs of
[{atom, _}] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_deref"/utf8>>,
line => 1928})
end,
{with_env, l4u@sys_bridge_ffi:deref(Ref), Env}.
-spec bif_reset(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_reset(Exprs, Env) ->
[{atom, Ref}, Expr] = case Exprs of
[{atom, _}, _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_reset"/utf8>>,
line => 1934})
end,
l4u@sys_bridge_ffi:reset_ref(Ref, Expr),
{with_env, Expr, Env}.
-spec bispform_quote(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_quote(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_quote"/utf8>>,
line => 1942})
end,
{with_env, Expr, Env}.
-spec make_container(l4u@l4u_type:expr(), list(l4u@l4u_type:expr())) -> l4u@l4u_type:expr().
make_container(Template_expr, Contents) ->
case Template_expr of
{list, _} ->
{list, Contents};
{vector, _} ->
{vector, Contents};
{dict, _} ->
{dict, Contents};
_ ->
undefined
end.
-spec get_contents(l4u@l4u_type:expr()) -> list(l4u@l4u_type:expr()).
get_contents(Expr) ->
case Expr of
{list, Contents} ->
Contents;
{vector, Contents@1} ->
Contents@1;
{dict, Contents@2} ->
Contents@2;
_ ->
[]
end.
-spec bif_cons(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_cons(Exprs, Env) ->
[Car, Cdr] = case Exprs of
[_, _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_cons"/utf8>>,
line => 1648})
end,
Car@1 = unwrap(Car),
Cdr@1 = unwrap(Cdr),
Contents = gleam@list:append([Car@1], get_contents(Cdr@1)),
{with_env, {list, Contents}, Env}.
-spec unquote_special(l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
unquote_special(Expr) ->
case Expr of
{list, [{symbol, <<"quote"/utf8>>}, nil]} ->
nil;
{list, Exprs} ->
{list, gleam@list:map(Exprs, fun unquote_special/1)};
_ ->
Expr
end.
-spec bif_slurp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_slurp(Exprs, Env) ->
[{string, Filename}] = case Exprs of
[{string, _}] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_slurp"/utf8>>,
line => 2126})
end,
Contents = l4u@sys_bridge_ffi:load_file(Filename),
{with_env, {string, Contents}, Env}.
-spec bif_tokenize(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_tokenize(Exprs, Env) ->
[{string, Src}] = case Exprs of
[{string, _}] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_tokenize"/utf8>>,
line => 2141})
end,
Tokenized = tokenize(Src, Env),
l4u@sys_bridge_ffi:dbgout2(<<"tokenize:"/utf8>>, Tokenized),
{with_env,
{list, gleam@list:map(Tokenized, fun(I) -> {string, I} end)},
Env}.
-spec bif_throw(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_throw(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_throw"/utf8>>,
line => 2262})
end,
l4u@sys_bridge_ffi:throw_expr(Expr),
{with_env, undefined, Env}.
-spec bif_meta(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_meta(Exprs, Env) ->
case Exprs of
[{with_meta, Expr, Meta}] ->
{with_env, Meta, Env};
_ ->
{with_env, nil, Env}
end.
-spec bif_with_meta(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_with_meta(Exprs, Env) ->
case Exprs of
[{with_meta, Expr, Meta}, New_meta] ->
{with_env, {with_meta, Expr, New_meta}, Env};
[Expr@1, New_meta@1] ->
{with_env, {with_meta, Expr@1, New_meta@1}, Env};
_ ->
l4u@sys_bridge_ffi:throw_err(<<"invalid with-meta"/utf8>>),
undefined
end.
-spec plist_to_map(
list(l4u@l4u_type:expr()),
gleam@dict:dict(binary(), l4u@l4u_type:expr())
) -> gleam@dict:dict(binary(), l4u@l4u_type:expr()).
plist_to_map(Plist, Acc) ->
case Plist of
[] ->
Acc;
[Key, Value | Rest] ->
Acc@1 = gleam@dict:insert(Acc, pstr(Key), Value),
plist_to_map(Rest, Acc@1);
_ ->
l4u@sys_bridge_ffi:throw_err(<<"plist_to_map: invalid plist"/utf8>>),
Acc
end.
-spec map_to_plist_(
list({binary(), l4u@l4u_type:expr()}),
list(l4u@l4u_type:expr())
) -> list(l4u@l4u_type:expr()).
map_to_plist_(Plist, Acc) ->
case Plist of
[] ->
Acc;
[{Key, Value} | Rest] ->
map_to_plist_(Rest, [intern_keyword(Key), Value | Acc]);
_ ->
l4u@sys_bridge_ffi:throw_err(<<"invalid map"/utf8>>),
Acc
end.
-spec map_to_plist(
gleam@dict:dict(binary(), l4u@l4u_type:expr()),
list(l4u@l4u_type:expr())
) -> list(l4u@l4u_type:expr()).
map_to_plist(Mapdata, Acc) ->
map_to_plist_(maps:to_list(Mapdata), []).
-spec dissoc(
list(l4u@l4u_type:expr()),
list(l4u@l4u_type:expr()),
list(l4u@l4u_type:expr())
) -> list(l4u@l4u_type:expr()).
dissoc(Plist, Keys, Acc) ->
case Plist of
[] ->
gleam@list:reverse(Acc);
[Key, Value | Rest] ->
case gleam@list:contains(Keys, Key) of
true ->
dissoc(
Rest,
gleam@list:filter(Keys, fun(K) -> K /= Key end),
Acc
);
_ ->
dissoc(Rest, Keys, [Value, Key | Acc])
end;
_ ->
l4u@sys_bridge_ffi:throw_err(<<"dissoc: invalid plist"/utf8>>),
gleam@list:reverse(Acc)
end.
-spec bif_dissoc(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_dissoc(Exprs, Env) ->
[{dict, Dict} | Keys] = case Exprs of
[{dict, _} | _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_dissoc"/utf8>>,
line => 2363})
end,
New_dict = {dict, dissoc(Dict, Keys, [])},
{with_env, New_dict, Env}.
-spec search_dict(list(l4u@l4u_type:expr()), l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
search_dict(Plist, Key) ->
case Plist of
[] ->
nil;
[Ekey, Evalue | Erest] when Ekey =:= Key ->
Evalue;
[Ekey@1, Evalue@1 | Erest@1] ->
search_dict(Erest@1, Key);
_ ->
l4u@sys_bridge_ffi:throw_err(<<"search_dict: invalid plist"/utf8>>),
nil
end.
-spec bif_get(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_get(Exprs, Env) ->
case Exprs of
[{dict, Dict}, Key] ->
{with_env, search_dict(Dict, Key), Env};
_ ->
{with_env, nil, Env}
end.
-spec dict_keys(list(l4u@l4u_type:expr()), list(l4u@l4u_type:expr())) -> list(l4u@l4u_type:expr()).
dict_keys(Plist, Acc) ->
case Plist of
[] ->
gleam@list:reverse(Acc);
[Key, Value | Rest] ->
dict_keys(Rest, [Key | Acc]);
_ ->
l4u@sys_bridge_ffi:throw_err(<<"dict_keys: invalid plist"/utf8>>),
[]
end.
-spec assoc(list(l4u@l4u_type:expr()), list(l4u@l4u_type:expr())) -> list(l4u@l4u_type:expr()).
assoc(Plist, Entries) ->
Assoc_keys = dict_keys(Entries, []),
Dissoced_plist = dissoc(Plist, Assoc_keys, []),
New_plist = gleam@list:append(Dissoced_plist, Entries).
-spec bif_assoc(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_assoc(Exprs, Env) ->
[{dict, Dict} | Entries] = case Exprs of
[{dict, _} | _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_assoc"/utf8>>,
line => 2334})
end,
New_dict = {dict, assoc(Dict, Entries)},
{with_env, New_dict, Env}.
-spec bif_keys(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_keys(Exprs, Env) ->
[{dict, Dict}] = case Exprs of
[{dict, _}] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_keys"/utf8>>,
line => 2407})
end,
{with_env, {list, dict_keys(Dict, [])}, Env}.
-spec dict_vals(list(l4u@l4u_type:expr()), list(l4u@l4u_type:expr())) -> l4u@l4u_type:expr().
dict_vals(Plist, Acc) ->
case Plist of
[] ->
{list, gleam@list:reverse(Acc)};
[Key, Value | Rest] ->
dict_vals(Rest, [Value | Acc]);
_ ->
l4u@sys_bridge_ffi:throw_err(<<"dict_vals: invalid plist"/utf8>>),
undefined
end.
-spec bif_vals(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_vals(Exprs, Env) ->
[{dict, Dict}] = case Exprs of
[{dict, _}] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_vals"/utf8>>,
line => 2426})
end,
{with_env, dict_vals(Dict, []), Env}.
-spec bif_gensym(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_gensym(Exprs, Env) ->
{with_env,
{symbol,
<<"$"/utf8,
(gleam@int:to_string(l4u@sys_bridge_ffi:unique_int()))/binary>>},
Env}.
-spec bif_time_ms(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_time_ms(Exprs, Env) ->
{with_env, {int, l4u@sys_bridge_ffi:tick_count() div 1000000}, Env}.
-spec bif_str(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_str(Exprs, Env) ->
{with_env,
{string,
begin
_pipe = gleam@list:map(Exprs, fun(Expr) -> show(Expr) end),
gleam@string:join(_pipe, <<""/utf8>>)
end},
Env}.
-spec bif_show(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_show(Exprs, Env) ->
{with_env,
{string,
begin
_pipe = gleam@list:map(Exprs, fun(Expr) -> show(Expr) end),
gleam@string:join(_pipe, <<""/utf8>>)
end},
Env}.
-spec instanciate_custom_type(
l4u@l4u_type:expr(),
gleam@dict:dict(binary(), l4u@l4u_type:expr())
) -> l4u@l4u_type:expr().
instanciate_custom_type(Cdef, Mapdata) ->
case uneval(Cdef) of
{list, []} ->
{list, []};
{list, Xs} ->
{list,
gleam@list:map(
Xs,
fun(X) -> instanciate_custom_type(X, Mapdata) end
)};
{keyword, Key} ->
case gleam@dict:get(Mapdata, Key) of
{ok, Value} ->
Value;
_ ->
l4u@sys_bridge_ffi:throw_err(<<"invalid custom type"/utf8>>),
undefined
end;
Any_value ->
Any_value
end.
-spec custom_type_to_map(
l4u@l4u_type:expr(),
l4u@l4u_type:expr(),
gleam@dict:dict(binary(), l4u@l4u_type:expr())
) -> gleam@dict:dict(binary(), l4u@l4u_type:expr()).
custom_type_to_map(Cdef, Cval, Acc) ->
case {uneval(Cdef), uneval(Cval)} of
{{list, []}, {list, []}} ->
Acc;
{{list, [Key | Rest_key]}, {list, [Val | Rest_val]}} ->
New_map = custom_type_to_map(Key, Val, Acc),
custom_type_to_map({list, Rest_key}, {list, Rest_val}, New_map);
{Key@1, Val@1} ->
gleam@dict:insert(Acc, pstr(Key@1), Val@1)
end.
-spec env_get_toplevel(l4u@l4u_type:env()) -> l4u@l4u_type:env().
env_get_toplevel(Env) ->
l4u@sys_bridge_ffi:process_dict_get(
erlang:element(3, Env),
<<"*toplevel*"/utf8>>
).
-spec env_get_(list(l4u@l4u_type:scope()), binary()) -> {ok,
l4u@l4u_type:expr()} |
{error, binary()}.
env_get_(Scopes, Key) ->
[Target_scope | Rest_scopes] = case Scopes of
[_ | _] -> Scopes;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"env_get_"/utf8>>,
line => 2822})
end,
case Target_scope of
{scope, Bindings} ->
case gleam@dict:get(Bindings, Key) of
{ok, Value} ->
{ok, Value};
{error, _} ->
case Rest_scopes of
[] ->
{error, <<"not found:: "/utf8, Key/binary>>};
_ ->
env_get_(Rest_scopes, Key)
end
end;
{process_dict, Pdic} ->
case l4u@sys_bridge_ffi:process_dict_get(Pdic, Key) of
undefined ->
case Rest_scopes of
[] ->
{error, <<"not found:: "/utf8, Key/binary>>};
_ ->
env_get_(Rest_scopes, Key)
end;
Value@1 ->
{ok, Value@1}
end
end.
-spec env_get(l4u@l4u_type:env(), binary()) -> {ok, l4u@l4u_type:expr()} |
{error, binary()}.
env_get(Env, Key) ->
case gleam@dict:get(erlang:element(4, Env), Key) of
{ok, Value} ->
{ok, Value};
{error, _} ->
case gleam@dict:get(erlang:element(5, Env), Key) of
{ok, Value@1} ->
{ok, Value@1};
{error, _} ->
env_get_(erlang:element(6, Env), Key)
end
end.
-spec get_macro(l4u@l4u_type:env(), l4u@l4u_type:expr()) -> {ok,
l4u@l4u_type:expr()} |
{error, binary()}.
get_macro(Env, Ast) ->
case Ast of
{list, [{symbol, Sym} | _]} ->
case env_get(Env, Sym) of
{ok, {macro, _, _, _, _} = Macroval} ->
{ok, Macroval};
_ ->
{error, <<"not macro"/utf8>>}
end;
_ ->
{error, <<"not macro"/utf8>>}
end.
-spec env_set_local(l4u@l4u_type:env(), binary(), l4u@l4u_type:expr()) -> l4u@l4u_type:env().
env_set_local(Env, Key, Value) ->
erlang:setelement(
4,
Env,
gleam@dict:insert(erlang:element(4, Env), Key, Value)
).
-spec env_add_local_scope(l4u@l4u_type:env(), l4u@l4u_type:scope()) -> l4u@l4u_type:env().
env_add_local_scope(Env, Scope) ->
erlang:setelement(6, Env, [Scope | erlang:element(6, Env)]).
-spec env_replace_local_scope(l4u@l4u_type:env(), l4u@l4u_type:scope()) -> l4u@l4u_type:env().
env_replace_local_scope(Env, Scope) ->
case erlang:element(6, Env) of
[_ | Rest_scopes] ->
erlang:setelement(6, Env, [Scope | Rest_scopes]);
_ ->
erlang:setelement(6, Env, [Scope])
end.
-spec get_bif_result_value(l4u@l4u_type:expr()) -> any().
get_bif_result_value(Expr) ->
{with_env, Value, _} = case Expr of
{with_env, _, _} -> Expr;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"get_bif_result_value"/utf8>>,
line => 2932})
end,
l4u_ffi:unsafe_corece(Value).
-spec env_update_global_aux(
l4u@l4u_type:env(),
binary(),
l4u@l4u_type:expr(),
l4u@l4u_type:expr()
) -> nil.
env_update_global_aux(Env, Key, Property_name, Property_value) ->
Auxpdic = l4u@sys_bridge_ffi:aux_pdic(
erlang:element(3, Env),
<<"aux"/utf8>>
),
case l4u@sys_bridge_ffi:process_dict_get(Auxpdic, Key) of
{dict, Dict} ->
l4u@sys_bridge_ffi:process_dict_set(
Auxpdic,
Key,
{dict, assoc(Dict, [Property_name, Property_value])}
);
_ ->
l4u@sys_bridge_ffi:process_dict_set(
Auxpdic,
Key,
{dict, [Property_name, Property_value]}
)
end,
nil.
-spec env_set_global(l4u@l4u_type:env(), binary(), l4u@l4u_type:expr()) -> l4u@l4u_type:env().
env_set_global(Env, Key, Value) ->
l4u@sys_bridge_ffi:process_dict_set(erlang:element(3, Env), Key, Value),
env_update_global_aux(
Env,
Key,
intern_keyword(<<"time"/utf8>>),
get_bif_result_value(bif_time_ms([], Env))
),
Env.
-spec bif_def_custom_type(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_def_custom_type(Exprs, Env) ->
[Name, Struct_def] = case Exprs of
[_, _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_def_custom_type"/utf8>>,
line => 2521})
end,
Name@1 = pstr(unwrap(Name)),
Struct_def@1 = unwrap(Struct_def),
Custom_type_def = {custom_type_def, Name@1, Struct_def@1},
New_env = env_set_global(Env, Name@1, Custom_type_def),
{with_env, Custom_type_def, New_env}.
-spec env_get_global_aux(l4u@l4u_type:env(), binary()) -> l4u@l4u_type:expr().
env_get_global_aux(Env, Key) ->
Auxpdic = l4u@sys_bridge_ffi:aux_pdic(
erlang:element(3, Env),
<<"aux"/utf8>>
),
case l4u@sys_bridge_ffi:process_dict_get(Auxpdic, Key) of
{dict, _} = Dict ->
Dict;
_ ->
undefined
end.
-spec env_get_global(l4u@l4u_type:env(), binary()) -> l4u@l4u_type:expr().
env_get_global(Env, Key) ->
l4u@sys_bridge_ffi:process_dict_get(erlang:element(3, Env), Key).
-spec bif_global_get(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_global_get(Exprs, Env) ->
[Name] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_global_get"/utf8>>,
line => 1457})
end,
Name@1 = pstr(uneval(Name)),
{with_env, env_get_global(Env, Name@1), Env}.
-spec trace(l4u@l4u_type:env(), list(l4u@l4u_type:expr()), boolean()) -> l4u@l4u_type:env().
trace(Env, Exprs, Tron) ->
case Exprs of
[] ->
Env;
[{list, Fnnames} | Rest] ->
trace(Env, Fnnames, Tron),
trace(Env, Rest, Tron);
[{keyword, Fnname} = Expr | Rest@1] ->
case env_get_global(Env, Fnname) of
{closure, Name, Params, Body, Closure_env} ->
env_set_global(
Env,
Fnname,
{closure,
Name,
Params,
Body,
erlang:setelement(
7,
Closure_env,
erlang:setelement(
3,
erlang:element(7, Closure_env),
Tron
)
)}
),
Env;
_ ->
Env
end,
trace(Env, Rest@1, Tron);
_ ->
Env
end.
-spec bif_trace(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_trace(Exprs, Env) ->
{with_env, nil, trace(Env, Exprs, true)}.
-spec bif_trace_clear(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_trace_clear(Exprs, Env) ->
{with_env, nil, trace(Env, Exprs, false)}.
-spec bif_instanciate_custom_type(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_instanciate_custom_type(Exprs, Env) ->
[Name, Mapdata] = case Exprs of
[_, _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_instanciate_custom_type"/utf8>>,
line => 2557})
end,
Name@1 = pstr(unwrap(Name)),
Plist@1 = case Mapdata of
{list, Plist} ->
Plist;
{vector, Plist} ->
Plist;
{dict, Plist} ->
Plist;
_ ->
l4u@sys_bridge_ffi:dbgout2(<<"invalid custom type:"/utf8>>, Mapdata),
l4u@sys_bridge_ffi:throw_err(<<"invalid custom type"/utf8>>),
[]
end,
Mapdata@1 = plist_to_map(Plist@1, maps:from_list([])),
_assert_subject = env_get_global(Env, Name@1),
{custom_type_def, _, Custom_type_def} = case _assert_subject of
{custom_type_def, _, _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_instanciate_custom_type"/utf8>>,
line => 2571})
end,
Instance = instanciate_custom_type(Custom_type_def, Mapdata@1),
{with_env, {custom_type, Name@1, Instance}, Env}.
-spec bif_custom_type_to_map(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_custom_type_to_map(Exprs, Env) ->
[Value] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_custom_type_to_map"/utf8>>,
line => 2602})
end,
{custom_type, Name, Custom_type_value} = case Value of
{custom_type, _, _} -> Value;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_custom_type_to_map"/utf8>>,
line => 2603})
end,
_assert_subject = env_get_global(Env, Name),
{custom_type_def, _, Custom_type_def} = case _assert_subject of
{custom_type_def, _, _} -> _assert_subject;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@2,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_custom_type_to_map"/utf8>>,
line => 2604})
end,
Mapdata = custom_type_to_map(
Custom_type_def,
Custom_type_value,
maps:from_list([])
),
Plist = map_to_plist(Mapdata, []),
{with_env, {dict, Plist}, Env}.
-spec env_erase_global(l4u@l4u_type:env(), binary()) -> l4u@l4u_type:expr().
env_erase_global(Env, Key) ->
l4u@sys_bridge_ffi:process_dict_erase(erlang:element(3, Env), Key).
-spec bispform_erase(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_erase(Exprs, Env) ->
[{symbol, Sym}] = case Exprs of
[{symbol, _}] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_erase"/utf8>>,
line => 1420})
end,
Old_value = env_erase_global(Env, Sym),
{with_env, Old_value, Env}.
-spec env_get_global_keys(l4u@l4u_type:env()) -> list(binary()).
env_get_global_keys(Env) ->
l4u@sys_bridge_ffi:process_dict_keys(erlang:element(3, Env)).
-spec global_keys(binary(), l4u@l4u_type:env()) -> list(binary()).
global_keys(Prefix, Env) ->
Keys = env_get_global_keys(Env),
case Prefix of
<<""/utf8>> ->
Keys;
_ ->
gleam@list:filter(
Keys,
fun(Key) -> gleam@string:starts_with(Key, Prefix) end
)
end.
-spec bif_global_keys(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_global_keys(Exprs, Env) ->
case Exprs of
[] ->
{with_env,
{list,
gleam@list:map(
global_keys(<<""/utf8>>, Env),
fun(Field@0) -> {string, Field@0} end
)},
Env};
[Prefix] ->
Prefix@1 = pstr(Prefix),
{with_env,
{list,
begin
_pipe = global_keys(Prefix@1, Env),
gleam@list:map(
_pipe,
fun(Field@0) -> {string, Field@0} end
)
end},
Env};
Unhandable ->
l4u@sys_bridge_ffi:throw_err(
<<"unhandable arguments at global_keys"/utf8>>
),
{with_env, undefined, Env}
end.
-spec dump_scopes_keys(list(l4u@l4u_type:scope())) -> binary().
dump_scopes_keys(Scopes) ->
case Scopes of
[] ->
<<""/utf8>>;
[{scope, Bindings}] ->
<<"(**)"/utf8>>;
[{scope, Bindings@1} | Rest] ->
<<<<<<"["/utf8,
(gleam@string:join(
gleam@dict:keys(Bindings@1),
<<","/utf8>>
))/binary>>/binary,
"]"/utf8>>/binary,
(dump_scopes_keys(Rest))/binary>>;
[_ | Rest@1] ->
dump_scopes_keys(Rest@1)
end.
-spec name_of(l4u@l4u_type:expr()) -> binary().
name_of(Expr) ->
case Expr of
{list, [{symbol, Name} | _]} ->
Name;
{symbol, Name@1} ->
Name@1;
{bif, Desc, _} ->
<<"bif-"/utf8, (erlang:element(2, Desc))/binary>>;
{closure, _, _, _, _} ->
<<"closure-"/utf8, "closure"/utf8>>;
{macro, _, _, _, _} ->
<<"macro-"/utf8, "closure"/utf8>>;
_ ->
<<"?"/utf8>>
end.
-spec trace_set_last_expr(l4u@l4u_type:expr(), l4u@l4u_type:env()) -> boolean().
trace_set_last_expr(Expr, Env) ->
l4u@sys_bridge_ffi:process_dict_set(
erlang:element(3, Env),
<<"last_expr"/utf8>>,
Expr
),
false.
-spec trace_set_last_funcall(l4u@l4u_type:expr(), l4u@l4u_type:env()) -> boolean().
trace_set_last_funcall(Expr, Env) ->
l4u@sys_bridge_ffi:process_dict_set(
erlang:element(3, Env),
<<"last_funcall"/utf8>>,
Expr
),
false.
-spec to_simple_str(l4u@l4u_type:expr()) -> binary().
to_simple_str(Expr) ->
case Expr of
{symbol, Name} ->
Name;
{string, Name@1} ->
Name@1;
{keyword, Name@2} ->
Name@2;
{int, Value} ->
gleam@int:to_string(Value);
true ->
<<"true"/utf8>>;
false ->
<<"false"/utf8>>;
nil ->
<<"nil"/utf8>>;
undefined ->
<<"undefined"/utf8>>;
_ ->
<<"*"/utf8>>
end.
-spec args_to_str(list(l4u@l4u_type:expr())) -> binary().
args_to_str(Args) ->
gleam@string:join(
gleam@list:map(Args, fun(Arg) -> to_simple_str(Arg) end),
<<" "/utf8>>
).
-spec dict_to_str(gleam@dict:dict(binary(), l4u@l4u_type:expr())) -> binary().
dict_to_str(Dict) ->
gleam@string:join(
begin
_pipe = maps:to_list(Dict),
gleam@list:map(
_pipe,
fun(Item) ->
{K, V} = Item,
<<<<(to_simple_str({string, K}))/binary, ":"/utf8>>/binary,
(to_simple_str(V))/binary>>
end
)
end,
<<", "/utf8>>
).
-spec indent(integer()) -> binary().
indent(Level) ->
case Level > 60 of
true ->
gleam@string:repeat(<<" "/utf8>>, 60);
_ ->
gleam@string:repeat(<<" "/utf8>>, Level)
end.
-spec vars_to_string(gleam@dict:dict(binary(), l4u@l4u_type:expr())) -> binary().
vars_to_string(Vars) ->
_pipe = maps:to_list(Vars),
_pipe@1 = gleam@list:map(
_pipe,
fun(Item) ->
{K, V} = Item,
<<<<(to_simple_str({string, K}))/binary, ":"/utf8>>/binary,
(to_simple_str(V))/binary>>
end
),
gleam@string:join(_pipe@1, <<", "/utf8>>).
-spec dump_local_vars(l4u@l4u_type:env()) -> binary().
dump_local_vars(Env) ->
<<<<"< "/utf8, (vars_to_string(erlang:element(4, Env)))/binary>>/binary,
" >"/utf8>>.
-spec inspect(l4u@l4u_type:expr()) -> binary().
inspect(Expr) ->
case Expr of
{with_env, Expr@1, _} ->
print(Expr@1);
undefined ->
<<"undefined"/utf8>>;
nil ->
<<"nil"/utf8>>;
true ->
<<"true"/utf8>>;
false ->
<<"false"/utf8>>;
{float, Val} ->
<<<<"(FLOAT "/utf8, (gleam@float:to_string(Val))/binary>>/binary,
")"/utf8>>;
{int, Val@1} ->
<<<<"(INT "/utf8, (gleam@int:to_string(Val@1))/binary>>/binary,
")"/utf8>>;
{string, Val@2} ->
<<<<"(STRING "/utf8, Val@2/binary>>/binary, ")"/utf8>>;
{symbol, Val@3} ->
<<<<"(SYMBOL "/utf8, Val@3/binary>>/binary, ")"/utf8>>;
{keyword, Val@4} ->
<<<<"(KEYWORD "/utf8, Val@4/binary>>/binary, ")"/utf8>>;
delimiter ->
<<","/utf8>>;
{list, Val@5} ->
<<<<"("/utf8,
(gleam@string:join(
gleam@list:map(Val@5, fun(Expr@2) -> print(Expr@2) end),
<<" "/utf8>>
))/binary>>/binary,
")"/utf8>>;
{vector, Val@6} ->
<<<<"["/utf8,
(gleam@string:join(
gleam@list:map(Val@6, fun(Expr@3) -> print(Expr@3) end),
<<" "/utf8>>
))/binary>>/binary,
"]"/utf8>>;
{dict, Val@7} ->
<<<<"{"/utf8,
(gleam@string:join(
gleam@list:map(Val@7, fun(Expr@4) -> print(Expr@4) end),
<<" "/utf8>>
))/binary>>/binary,
"}"/utf8>>;
{closure, Desc, Params, Body, Closure_env} ->
Body@1 = gleam@list:map(Body, fun(E) -> print(E) end),
<<<<<<<<<<<<<<<<<<<<"(CLOSURE "/utf8,
(erlang:element(2, Desc))/binary>>/binary,
" ("/utf8>>/binary,
(gleam@string:join(
Params,
<<" "/utf8>>
))/binary>>/binary,
")\n "/utf8>>/binary,
(gleam@string:join(Body@1, <<" "/utf8>>))/binary>>/binary,
")"/utf8>>/binary,
"\n "/utf8>>/binary,
(dump_local_vars(Closure_env))/binary>>/binary,
"\n "/utf8>>/binary,
(dump_scopes_keys(erlang:element(6, Closure_env)))/binary>>;
{macro, Info, Params@1, Body@2, Closure_env@1} ->
Body@3 = gleam@list:map(Body@2, fun(E@1) -> print(E@1) end),
<<<<<<<<"(MACRO ("/utf8,
(gleam@string:join(Params@1, <<" "/utf8>>))/binary>>/binary,
") "/utf8>>/binary,
(gleam@string:join(Body@3, <<" "/utf8>>))/binary>>/binary,
")"/utf8>>;
{atom, Ref} ->
<<"#<atom>"/utf8>>;
{bif, Desc@1, _} ->
<<<<"#<bif:"/utf8, (erlang:element(2, Desc@1))/binary>>/binary,
">"/utf8>>;
{bispform, Desc@2, _} ->
<<<<"#<bispform:"/utf8, (erlang:element(2, Desc@2))/binary>>/binary,
">"/utf8>>;
{with_meta, Expr@5, Meta} ->
<<<<<<<<"(with-meta "/utf8, (inspect(Expr@5))/binary>>/binary,
" "/utf8>>/binary,
(inspect(Meta))/binary>>/binary,
")"/utf8>>;
{custom_type_def, Name, Expr@6} ->
<<<<<<<<"(custom-type-def "/utf8, Name/binary>>/binary, " "/utf8>>/binary,
(print(Expr@6))/binary>>/binary,
">"/utf8>>;
{custom_type, Name@1, Expr@7} ->
<<<<<<<<"("/utf8, Name@1/binary>>/binary, " "/utf8>>/binary,
(print(Expr@7))/binary>>/binary,
" )"/utf8>>;
_ ->
l4u@sys_bridge_ffi:internal_form(Expr)
end.
-spec describe(l4u@l4u_type:expr()) -> binary().
describe(Expr) ->
case Expr of
{with_env, Expr@1, _} ->
print(Expr@1);
undefined ->
<<"(SPECIAL undefined)"/utf8>>;
nil ->
<<"(SPECIAL nil)"/utf8>>;
true ->
<<"(BOOL true)"/utf8>>;
false ->
<<"(BOOL false)"/utf8>>;
{float, Val} ->
<<<<"(FLOAT "/utf8, (gleam@float:to_string(Val))/binary>>/binary,
")"/utf8>>;
{int, Val@1} ->
<<<<"(INT "/utf8, (gleam@int:to_string(Val@1))/binary>>/binary,
")"/utf8>>;
{string, Val@2} ->
<<<<"(STRING "/utf8, Val@2/binary>>/binary, ")"/utf8>>;
{symbol, Val@3} ->
<<<<"(SYMBOL "/utf8, Val@3/binary>>/binary, ")"/utf8>>;
{keyword, Val@4} ->
<<<<"(KEYWORD "/utf8, Val@4/binary>>/binary, ")"/utf8>>;
delimiter ->
<<","/utf8>>;
{list, Val@5} ->
<<<<"("/utf8,
(gleam@string:join(
gleam@list:map(Val@5, fun(Expr@2) -> print(Expr@2) end),
<<" "/utf8>>
))/binary>>/binary,
")"/utf8>>;
{vector, Val@6} ->
<<<<"["/utf8,
(gleam@string:join(
gleam@list:map(Val@6, fun(Expr@3) -> print(Expr@3) end),
<<" "/utf8>>
))/binary>>/binary,
"]"/utf8>>;
{dict, Val@7} ->
<<<<"{"/utf8,
(gleam@string:join(
gleam@list:map(Val@7, fun(Expr@4) -> print(Expr@4) end),
<<" "/utf8>>
))/binary>>/binary,
"}"/utf8>>;
{closure, Desc, Params, Body, Closure_env} ->
Body@1 = gleam@list:map(Body, fun(E) -> print(E) end),
<<<<<<<<<<<<<<<<(erlang:element(3, Desc))/binary, "\n"/utf8>>/binary,
"(CLOSURE "/utf8>>/binary,
(erlang:element(2, Desc))/binary>>/binary,
" ("/utf8>>/binary,
(gleam@string:join(Params, <<" "/utf8>>))/binary>>/binary,
")\n "/utf8>>/binary,
(gleam@string:join(Body@1, <<" "/utf8>>))/binary>>/binary,
")"/utf8>>;
{macro, Desc@1, Params@1, Body@2, Closure_env@1} ->
Body@3 = gleam@list:map(Body@2, fun(E@1) -> print(E@1) end),
<<<<<<<<<<<<<<<<(erlang:element(3, Desc@1))/binary, "\n"/utf8>>/binary,
"(MACRO "/utf8>>/binary,
(erlang:element(2, Desc@1))/binary>>/binary,
" ("/utf8>>/binary,
(gleam@string:join(Params@1, <<" "/utf8>>))/binary>>/binary,
")\n "/utf8>>/binary,
(gleam@string:join(Body@3, <<" "/utf8>>))/binary>>/binary,
")"/utf8>>;
{atom, Ref} ->
<<"#<atom>"/utf8>>;
{bif, Desc@2, _} ->
<<<<<<"builtin function: "/utf8,
(erlang:element(2, Desc@2))/binary>>/binary,
"\n"/utf8>>/binary,
(erlang:element(3, Desc@2))/binary>>;
{bispform, Desc@3, _} ->
<<<<<<"special form: "/utf8, (erlang:element(2, Desc@3))/binary>>/binary,
"\n"/utf8>>/binary,
(erlang:element(3, Desc@3))/binary>>;
{with_meta, Expr@5, Meta} ->
<<<<<<<<"(with-meta "/utf8, (inspect(Expr@5))/binary>>/binary,
" "/utf8>>/binary,
(inspect(Meta))/binary>>/binary,
")"/utf8>>;
_ ->
l4u@sys_bridge_ffi:internal_form(Expr)
end.
-spec bif_inspect(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_inspect(Exprs, Env) ->
[First] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_inspect"/utf8>>,
line => 1720})
end,
Str = inspect(uneval(First)),
l4u@sys_bridge_ffi:console_writeln(Str),
{with_env, nil, Env}.
-spec bif_describe(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_describe(Exprs, Env) ->
[First] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_describe"/utf8>>,
line => 1732})
end,
Str = describe(uneval(First)),
l4u@sys_bridge_ffi:console_writeln(Str),
{with_env, nil, Env}.
-spec dump_dict(
gleam@dict:dict(binary(), l4u@l4u_type:expr()),
l4u@l4u_type:env()
) -> boolean().
dump_dict(Dict, Env) ->
gleam@list:each(
maps:to_list(Dict),
fun(Item) ->
{K, V} = Item,
l4u@sys_bridge_ffi:dbgout1(
<<<<(inspect({string, K}))/binary, " => "/utf8>>/binary,
(inspect(V))/binary>>
)
end
),
false.
-spec dump_closure(binary(), l4u@l4u_type:expr()) -> boolean().
dump_closure(Msg, Expr) ->
{closure, Desc, Params, Progn, Closure_env} = case Expr of
{closure, _, _, _, _} -> Expr;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"dump_closure"/utf8>>,
line => 3018})
end,
l4u@sys_bridge_ffi:dbgout1(
<<"--------------------------------------------------------------------"/utf8>>
),
l4u@sys_bridge_ffi:dbgout1(
<<<<<<"# dump_closure: "/utf8, Msg/binary>>/binary, " "/utf8>>/binary,
(erlang:element(2, Desc))/binary>>
),
l4u@sys_bridge_ffi:dbgout2(<<"params:"/utf8>>, Params),
l4u@sys_bridge_ffi:dbgout2(<<"progn:"/utf8>>, Progn),
l4u@sys_bridge_ffi:dbgout2(
<<"closure_env:"/utf8>>,
<<(dump_local_vars(Closure_env))/binary,
(dump_scopes_keys(erlang:element(6, Closure_env)))/binary>>
),
false.
-spec local_scopes_to_string(list(l4u@l4u_type:scope()), list(binary())) -> binary().
local_scopes_to_string(Scopes, Acc) ->
case Scopes of
[{scope, Bindings} | Rest] ->
local_scopes_to_string(Rest, [vars_to_string(Bindings) | Acc]);
_ ->
gleam@string:join(gleam@list:reverse(Acc), <<" "/utf8>>)
end.
-spec info_to_str(l4u@l4u_type:info()) -> binary().
info_to_str(Inf) ->
case Inf of
{info, Name, Level} ->
<<<<Name/binary, ": "/utf8>>/binary,
(gleam@int:to_string(Level))/binary>>
end.
-spec dump_env(binary(), l4u@l4u_type:env()) -> boolean().
dump_env(Title, Env) ->
l4u@sys_bridge_ffi:dbgout1(
<<"--------------------------------------------------------------------"/utf8>>
),
l4u@sys_bridge_ffi:dbgout1(
<<<<<<"# dump_env: "/utf8, Title/binary>>/binary, " "/utf8>>/binary,
(info_to_str(erlang:element(2, Env)))/binary>>
),
l4u@sys_bridge_ffi:dbgout2(
<<"$$eval_expr_$$:"/utf8>>,
<<(dump_local_vars(Env))/binary,
(dump_scopes_keys(erlang:element(6, Env)))/binary>>
),
false.
-spec bif_inspect_env(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_inspect_env(Exprs, Env) ->
dump_env(<<"inspect-env"/utf8>>, Env),
{with_env, nil, Env}.
-spec repl_print(l4u@l4u_type:expr()) -> nil.
repl_print(Result) ->
case Result of
{printable, {string, <<""/utf8>>}} ->
nil;
{printable, Printable} ->
l4u@sys_bridge_ffi:console_writeln(show(Result));
_ ->
l4u@sys_bridge_ffi:console_writeln(print(Result))
end.
-spec initialize() -> boolean().
initialize() ->
gleam_bridge:init_gleam_bridge().
-spec dump_list(list(binary()), l4u@l4u_type:env()) -> nil.
dump_list(List, Env) ->
gleam@list:each(List, fun(E) -> l4u@sys_bridge_ffi:dbgout1(E) end).
-spec trace_closure_call(
l4u@l4u_type:env(),
l4u@l4u_type:expr(),
any(),
gleam@dict:dict(binary(), l4u@l4u_type:expr())
) -> integer().
trace_closure_call(Env, Callable, Ecallable, Bindings) ->
Ip = l4u@sys_bridge_ffi:process_dict_get(
erlang:element(3, Env),
<<"*trace_ip"/utf8>>
),
Level = l4u@sys_bridge_ffi:process_dict_get(
erlang:element(3, Env),
<<"*trace_level"/utf8>>
),
(true andalso erlang:element(3, erlang:element(7, Env))) andalso begin
gleam@io:println(
<<<<<<<<<<<<<<(indent(Level))/binary, "- "/utf8>>/binary,
(gleam@int:to_string(Ip))/binary>>/binary,
": ("/utf8>>/binary,
(to_simple_str(Callable))/binary>>/binary,
" "/utf8>>/binary,
(dict_to_str(Bindings))/binary>>/binary,
")"/utf8>>
),
true
end,
l4u@sys_bridge_ffi:process_dict_set(
erlang:element(3, Env),
<<"*trace_level"/utf8>>,
Level + 1
),
l4u@sys_bridge_ffi:process_dict_set(
erlang:element(3, Env),
<<"*trace_ip"/utf8>>,
Ip + 1
),
Ip.
-spec trace_closure_return(
l4u@l4u_type:env(),
l4u@l4u_type:expr(),
any(),
l4u@l4u_type:expr(),
integer()
) -> boolean().
trace_closure_return(Env, Callable, Ecallable, Rexpr, Ip) ->
Level = l4u@sys_bridge_ffi:process_dict_get(
erlang:element(3, Env),
<<"*trace_level"/utf8>>
)
- 1,
l4u@sys_bridge_ffi:process_dict_set(
erlang:element(3, Env),
<<"*trace_level"/utf8>>,
Level
),
(true andalso erlang:element(3, erlang:element(7, Env))) andalso begin
gleam@io:println(
<<<<<<<<<<<<(indent(Level))/binary, "- "/utf8>>/binary,
(gleam@int:to_string(Ip))/binary>>/binary,
": "/utf8>>/binary,
(to_simple_str(Callable))/binary>>/binary,
" returned "/utf8>>/binary,
(to_simple_str(Rexpr))/binary>>
),
true
end.
-spec generate_local_env(
binary(),
l4u@l4u_type:env(),
gleam@dict:dict(binary(), l4u@l4u_type:expr()),
gleam@dict:dict(binary(), l4u@l4u_type:expr())
) -> l4u@l4u_type:env().
generate_local_env(Name, Env, Bindings, A_bindings) ->
case scope_type_overwrite_local of
scope_type_overwrite_local ->
generate_local_env__overwrite_local(Name, Env, Bindings, A_bindings);
scope_type_simple_scopes ->
generate_local_env__simple_scope(Name, Env, Bindings, A_bindings);
scope_type_opt_scopes ->
generate_local_env__opt_scopes(Name, Env, Bindings, A_bindings)
end.
-spec repl_loop(
l4u@l4u_type:env(),
{ok, l4u@l4u_type:env()} | {error, l4u@l4u_type:expr()},
binary()
) -> any().
repl_loop(Env, Result, Prompt) ->
case Result of
{ok, New_env} ->
repl(New_env, Prompt);
{error, Err} ->
l4u@sys_bridge_ffi:console_writeln(
<<"Error: "/utf8,
(l4u@sys_bridge_ffi:error_to_string(
Err,
erlang:element(2, erlang:element(7, Env))
))/binary>>
),
case erlang:element(2, erlang:element(7, Env)) of
true ->
dump_env(<<"repl"/utf8>>, Env),
l4u@sys_bridge_ffi:dbgout2(
<<"last funcall:"/utf8>>,
l4u@sys_bridge_ffi:process_dict_get(
erlang:element(3, Env),
<<"last_funcall"/utf8>>
)
),
l4u@sys_bridge_ffi:dbgout2(
<<"last expr:"/utf8>>,
l4u@sys_bridge_ffi:process_dict_get(
erlang:element(3, Env),
<<"last_expr"/utf8>>
)
);
false ->
false
end,
repl(Env, Prompt)
end.
-spec repl(l4u@l4u_type:env(), binary()) -> any().
repl(Env, Prompt) ->
true andalso trace_set_last_funcall(undefined, Env),
Line = l4u@sys_bridge_ffi:console_readline(Prompt),
case gleam@string:length(gleam@string:trim(Line)) of
0 ->
l4u@sys_bridge_ffi:console_writeln(<<""/utf8>>),
repl(Env, Prompt);
_ ->
Result@1 = l4u@sys_bridge_ffi:catch_ex(
fun() ->
l4u@sys_bridge_ffi:process_dict_set(
erlang:element(3, Env),
<<"*trace_ip"/utf8>>,
0
),
_assert_subject = rep(Line, Env),
{with_env, Result, New_env} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"repl"/utf8>>,
line => 3221})
end,
repl_print(Result),
New_env
end
),
repl_loop(Env, Result@1, Prompt)
end.
-spec quasiquote(l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
quasiquote(Ast) ->
case Ast of
{list, [{symbol, <<"unquote"/utf8>>}, Arg]} ->
Arg;
{list, L} ->
gleam@list:fold_right(
L,
{list, []},
fun(Acc, X) -> qq_loop(X, Acc) end
);
{vector, L@1} ->
{list,
[{symbol, <<"vec"/utf8>>},
gleam@list:fold_right(
L@1,
{list, []},
fun(Acc@1, X@1) -> qq_loop(X@1, Acc@1) end
)]};
{symbol, _} ->
{list, [{symbol, <<"quote"/utf8>>}, Ast]};
{dict, _} ->
{list, [{symbol, <<"quote"/utf8>>}, Ast]};
_ ->
Ast
end.
-spec qq_loop(l4u@l4u_type:expr(), l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
qq_loop(Elt, Acc) ->
case Elt of
{list, [{symbol, <<"splice-unquote"/utf8>>}, Arg]} ->
{list, gleam@list:append([{symbol, <<"concat"/utf8>>}, Arg], [Acc])};
_ ->
{list,
gleam@list:append(
[{symbol, <<"cons"/utf8>>}, quasiquote(Elt)],
[Acc]
)}
end.
-spec bispform_quasiquote2(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_quasiquote2(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_quasiquote2"/utf8>>,
line => 2054})
end,
Eexpr = quasiquote(Expr).
-spec bispform_quasiquote_expand2(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_quasiquote_expand2(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_quasiquote_expand2"/utf8>>,
line => 2060})
end,
Eexpr = quasiquote(Expr),
{with_env, Eexpr, Env}.
-spec compare_dict(list(l4u@l4u_type:expr()), list(l4u@l4u_type:expr())) -> gleam@order:order().
compare_dict(Us, Vs) ->
Us@1 = gleam@list:sort(Us, fun(U, V) -> compare(U, V) end),
Vs@1 = gleam@list:sort(Vs, fun(U@1, V@1) -> compare(U@1, V@1) end),
compare_list(Us@1, Vs@1).
-spec compare(l4u@l4u_type:expr(), l4u@l4u_type:expr()) -> gleam@order:order().
compare(U, V) ->
case {U, V} of
{{int, U@1}, {int, V@1}} ->
gleam@int:compare(U@1, V@1);
{{float, U@2}, {float, V@2}} ->
gleam@float:compare(U@2, V@2);
{{float, U@3}, {int, V@3}} ->
gleam@float:compare(U@3, gleam@int:to_float(V@3));
{{int, U@4}, {float, V@4}} ->
gleam@float:compare(gleam@int:to_float(U@4), V@4);
{{string, U@5}, {string, V@5}} ->
gleam@string:compare(U@5, V@5);
{{symbol, U@6}, {symbol, V@6}} ->
gleam@string:compare(U@6, V@6);
{{keyword, U@7}, {keyword, V@7}} ->
gleam@string:compare(U@7, V@7);
{{list, Us}, {list, Vs}} ->
compare_list(Us, Vs);
{{vector, Us@1}, {vector, Vs@1}} ->
compare_list(Us@1, Vs@1);
{{vector, Us@2}, {list, Vs@2}} ->
compare_list(Us@2, Vs@2);
{{list, Us@3}, {vector, Vs@3}} ->
compare_list(Us@3, Vs@3);
{{dict, Us@4}, {dict, Vs@4}} ->
compare_dict(Us@4, Vs@4);
{_, _} ->
case U =:= V of
true ->
eq;
false ->
l4u@sys_bridge_ffi:compare_any(U, V)
end
end.
-spec is_equal(l4u@l4u_type:expr(), l4u@l4u_type:expr()) -> boolean().
is_equal(First, Second) ->
case {First, Second} of
{{int, X}, {int, Y}} ->
X =:= Y;
{{float, X@1}, {float, Y@1}} ->
X@1 =:= Y@1;
{{string, X@2}, {string, Y@2}} ->
X@2 =:= Y@2;
{{symbol, X@3}, {symbol, Y@3}} ->
X@3 =:= Y@3;
{{keyword, X@4}, {keyword, Y@4}} ->
X@4 =:= Y@4;
{{list, X@5}, {list, Y@5}} ->
compare(First, Second) =:= eq;
{{vector, X@6}, {vector, Y@6}} ->
compare(First, Second) =:= eq;
{{vector, X@7}, {list, Y@7}} ->
compare(First, Second) =:= eq;
{{list, X@8}, {vector, Y@8}} ->
compare(First, Second) =:= eq;
{{dict, X@9}, {dict, Y@9}} ->
compare(First, Second) =:= eq;
{_, _} ->
First =:= Second
end.
-spec bif_eqp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_eqp(Exprs, Env) ->
[X | Xs] = case Exprs of
[_ | _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_eqp"/utf8>>,
line => 1243})
end,
X@1 = unwrap(X),
Result = case gleam@list:all(Xs, fun(E) -> is_equal(X@1, unwrap(E)) end) of
true ->
true;
false ->
false
end,
{with_env, Result, Env}.
-spec compare_list(list(l4u@l4u_type:expr()), list(l4u@l4u_type:expr())) -> gleam@order:order().
compare_list(Us, Vs) ->
case {Us, Vs} of
{[], []} ->
eq;
{[], _} ->
lt;
{_, []} ->
gt;
{[U | Us@1], [V | Vs@1]} ->
case compare(U, V) of
eq ->
compare_list(Us@1, Vs@1);
Result ->
Result
end
end.
-spec bif_ltp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_ltp(Exprs, Env) ->
Result = case Exprs of
[] ->
false;
[X] ->
true;
[X@1, Y | Rest] ->
case compare(X@1, Y) of
lt ->
bif_ltp([Y | Rest], Env);
_ ->
false
end
end,
{with_env, Result, Env}.
-spec bif_gtp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_gtp(Exprs, Env) ->
Result = case Exprs of
[] ->
false;
[X] ->
true;
[X@1, Y | Rest] ->
case compare(X@1, Y) of
gt ->
bif_gtp([Y | Rest], Env);
_ ->
false
end
end,
{with_env, Result, Env}.
-spec bif_lteqp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_lteqp(Exprs, Env) ->
Result = case Exprs of
[] ->
false;
[X] ->
true;
[X@1, Y | Rest] ->
case compare(X@1, Y) of
lt ->
bif_lteqp([Y | Rest], Env);
eq ->
bif_lteqp([Y | Rest], Env);
_ ->
false
end
end,
{with_env, Result, Env}.
-spec bif_gteqp(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_gteqp(Exprs, Env) ->
Result = case Exprs of
[] ->
false;
[X] ->
true;
[X@1, Y | Rest] ->
case compare(X@1, Y) of
gt ->
bif_gteqp([Y | Rest], Env);
eq ->
bif_gteqp([Y | Rest], Env);
_ ->
false
end
end,
{with_env, Result, Env}.
-spec parse_list(
list(binary()),
list(l4u@l4u_type:expr()),
binary(),
l4u@l4u_type:env()
) -> {list(l4u@l4u_type:expr()), list(binary())}.
parse_list(Tokens, Acc, Terminator, Env) ->
case Tokens of
[Token | Rest] when Token =:= Terminator ->
{gleam@list:reverse(Acc), Rest};
_ ->
{Expr, Rest@1} = parse(Tokens, Env),
parse_list_delimiter(Rest@1, [Expr | Acc], Terminator, Env)
end.
-spec parse_list_delimiter(
list(binary()),
list(l4u@l4u_type:expr()),
binary(),
l4u@l4u_type:env()
) -> {list(l4u@l4u_type:expr()), list(binary())}.
parse_list_delimiter(Tokens, Acc, Terminator, Env) ->
case Tokens of
[<<","/utf8>> | Rest] ->
parse_list(Rest, Acc, Terminator, Env);
_ ->
parse_list(Tokens, Acc, Terminator, Env)
end.
-spec parse_(list(binary()), l4u@l4u_type:env()) -> {l4u@l4u_type:expr(),
list(binary())}.
parse_(Tokens, Env) ->
case Tokens of
[<<"@"/utf8>> | Rest_token] ->
{Expr, Rest2} = parse(Rest_token, Env),
{{list, [{symbol, <<"deref"/utf8>>}, Expr]}, Rest2};
[<<"^"/utf8>> | Rest_token@1] ->
{Expr@1, Rest2@1} = parse(Rest_token@1, Env),
{Expr2, Rest3} = parse(Rest2@1, Env),
{{list, [{symbol, <<"with-meta"/utf8>>}, Expr2, Expr@1]}, Rest3};
[<<"'"/utf8>> | Rest_token@2] ->
{Expr@2, Rest2@2} = parse(Rest_token@2, Env),
{{list, [{symbol, <<"quote"/utf8>>}, Expr@2]}, Rest2@2};
[<<"`"/utf8>> | Rest_token@3] ->
{Expr@3, Rest2@3} = parse(Rest_token@3, Env),
{{list, [{symbol, <<"quasiquote"/utf8>>}, Expr@3]}, Rest2@3};
[<<"~"/utf8>> | Rest_token@4] ->
{Expr@4, Rest2@4} = parse(Rest_token@4, Env),
{{list, [{symbol, <<"unquote"/utf8>>}, Expr@4]}, Rest2@4};
[<<"~@"/utf8>> | Rest_token@5] ->
{Expr@5, Rest2@5} = parse(Rest_token@5, Env),
{{list, [{symbol, <<"splice-unquote"/utf8>>}, Expr@5]}, Rest2@5};
[<<"("/utf8>> | Rest_tokens] ->
{Exprs, Rest2@6} = parse_list(Rest_tokens, [], <<")"/utf8>>, Env),
{{list, Exprs}, Rest2@6};
[<<"["/utf8>> | Rest_tokens@1] ->
{Exprs@1, Rest2@7} = parse_list(
Rest_tokens@1,
[],
<<"]"/utf8>>,
Env
),
{{vector, Exprs@1}, Rest2@7};
[<<"{"/utf8>> | Rest_tokens@2] ->
{Exprs@2, Rest2@8} = parse_list(
Rest_tokens@2,
[],
<<"}"/utf8>>,
Env
),
{{dict, Exprs@2}, Rest2@8};
[Token | Rest_tokens@3] ->
{parse_expr(Token, Env), Rest_tokens@3};
_ ->
l4u@sys_bridge_ffi:dbgout2(<<"invalid token:"/utf8>>, Tokens),
l4u@sys_bridge_ffi:throw_err(<<"invalid token"/utf8>>),
{undefined, []}
end.
-spec parse(list(binary()), l4u@l4u_type:env()) -> {l4u@l4u_type:expr(),
list(binary())}.
parse(Tokens, Env) ->
{Expr, Rest} = parse_(Tokens, Env),
case erlang:element(2, erlang:element(7, Env)) of
true ->
case Expr of
{list, _} ->
false andalso l4u@sys_bridge_ffi:dbgout2(
<<"parse:"/utf8>>,
Expr
),
nil;
_ ->
false andalso l4u@sys_bridge_ffi:dbgout2(
<<"parse:"/utf8>>,
Expr
),
nil
end;
_ ->
nil
end,
Expr2 = apply_macro(Expr, Env),
{Expr2, Rest}.
-spec read_(list(binary()), list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> list(l4u@l4u_type:expr()).
read_(Tokens, Acc, Env) ->
case Tokens of
[] ->
gleam@list:reverse(Acc);
_ ->
{Expr, Rest} = parse(Tokens, Env),
read_(Rest, [Expr | Acc], Env)
end.
-spec read(binary(), l4u@l4u_type:env()) -> list(l4u@l4u_type:expr()).
read(Src, Env) ->
Tokens = tokenize(Src, Env),
Exprs = read_(Tokens, [], Env),
Exprs.
-spec bif_read_string(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_read_string(Exprs, Env) ->
[{string, Str}] = case Exprs of
[{string, _}] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_read_string"/utf8>>,
line => 2133})
end,
Exprs@1 = read(Str, Env),
[Expr | _] = case Exprs@1 of
[_ | _] -> Exprs@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_read_string"/utf8>>,
line => 2135})
end,
{with_env, Expr, Env}.
-spec bif_read(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_read(Exprs, Env) ->
[{string, Src}] = case Exprs of
[{string, _}] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_read"/utf8>>,
line => 2148})
end,
_assert_subject = read(Src, Env),
[Expr] = case _assert_subject of
[_] -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_read"/utf8>>,
line => 2150})
end,
{with_env, Expr, Env}.
-spec eval_contents(
list(l4u@l4u_type:expr()),
list(l4u@l4u_type:expr()),
l4u@l4u_type:env()
) -> {list(l4u@l4u_type:expr()), l4u@l4u_type:env()}.
eval_contents(Exprs, Acc, Env) ->
case Exprs of
[] ->
{gleam@list:reverse(Acc), Env};
[Expr | Rest] ->
_assert_subject = eval([Expr], undefined, Env),
{with_env, Result, New_env} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"eval_contents"/utf8>>,
line => 577})
end,
eval_contents(Rest, [Result | Acc], New_env)
end.
-spec eval(list(l4u@l4u_type:expr()), l4u@l4u_type:expr(), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
eval(Exprs, Result, Env) ->
case Exprs of
[] ->
{with_env, Result, Env};
[{with_env, Result@1, New_env} = Ret] ->
Ret;
[{continuation, Progn, New_env@1} = Ret@1] ->
eval(Progn, undefined, New_env@1);
[Expr] ->
Ret@2 = eval_expr(Expr, Env),
eval([Ret@2], undefined, Env);
[Expr@1 | Rest] ->
_assert_subject = eval([Expr@1], undefined, Env),
{with_env, Rexpr, Renv} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"eval"/utf8>>,
line => 563})
end,
eval(Rest, Rexpr, Renv)
end.
-spec eval_expr(l4u@l4u_type:expr(), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
eval_expr(Expr, Env) ->
case Expr of
{list, [{symbol, <<"meta"/utf8>>}, {with_meta, _, Meta}]} ->
{with_env, Meta, Env};
_ ->
eval_expr_(unwrap(Expr), Env)
end.
-spec eval_expr_(l4u@l4u_type:expr(), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
eval_expr_(Expr, Env) ->
Result = case Expr of
{list, [Callable | Args]} ->
(true andalso erlang:element(3, erlang:element(7, Env))) andalso trace_set_last_funcall(
Expr,
Env
),
_assert_subject = case Callable of
{list, _} ->
eval([Callable], undefined, Env);
_ ->
eval_expr_(Callable, Env)
end,
{with_env, Ecallable, New_env} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"eval_expr_"/utf8>>,
line => 738})
end,
case unwrap(Ecallable) of
{bispform, _, F} ->
F(Args, New_env);
{bif, _, F@1} ->
{Eargs, New_env@1} = eval_funcall_args(Args, New_env),
F@1(Eargs, New_env@1);
{native_function, _, _} = Nt_fun ->
{Eargs@1, New_env@2} = eval_funcall_args(Args, New_env),
Rexpr = l4u@bif_lib:invoke_native_function(
l4u_ffi:unsafe_corece(Nt_fun),
Eargs@1
),
{with_env, Rexpr, New_env@2};
{closure, _, Params, Progn, Closure_env} = Closure ->
{Eargs@2, New_env@3} = eval_funcall_args(Args, New_env),
Bindings = bind_args(maps:from_list([]), Params, Eargs@2),
Ip = trace_closure_call(
Closure_env,
Callable,
Ecallable,
Bindings
),
New_closure_env = generate_local_env(
<<"call closure"/utf8>>,
Closure_env,
Bindings,
erlang:element(5, Env)
),
_assert_subject@1 = local_continuation(
Progn,
New_closure_env,
New_env@3
),
{with_env, Rexpr@1, _} = Return = case _assert_subject@1 of
{with_env, _, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"eval_expr_"/utf8>>,
line => 788})
end,
trace_closure_return(
Closure_env,
Callable,
Ecallable,
Rexpr@1,
Ip
),
Return;
{macro, Info, Params@1, Progn@1, Macro_env} ->
Bindings@1 = maps:from_list([]),
Bindings@2 = bind_args(Bindings@1, Params@1, Args),
New_local_env = erlang:setelement(
6,
Macro_env,
[{scope, Bindings@2} | erlang:element(6, Env)]
),
local_continuation(Progn@1, New_local_env, Env);
_ ->
{with_env, undefined, Env}
end;
{vector, Contents} ->
{Eargs@3, New_env@4} = eval_contents(Contents, [], Env),
{with_env, {vector, Eargs@3}, New_env@4};
{dict, Contents@1} ->
{Eargs@4, New_env@5} = eval_contents(Contents@1, [], Env),
{with_env, {dict, Eargs@4}, New_env@5};
{symbol, Sym} ->
(true andalso erlang:element(3, erlang:element(7, Env))) andalso trace_set_last_expr(
Expr,
Env
),
case env_get(Env, Sym) of
{ok, Value} ->
{with_env, Value, Env};
_ ->
l4u@sys_bridge_ffi:throw_err(
<<<<"'"/utf8, Sym/binary>>/binary, "' not found"/utf8>>
),
{with_env, undefined, Env}
end;
{ex_var, Etype, Esym} ->
case persistent_term:get(Etype, undefined) of
undefined ->
l4u@sys_bridge_ffi:throw_err(
<<<<"'"/utf8, Etype/binary>>/binary,
"' not found"/utf8>>
),
{with_env, undefined, Env};
{closure, _, _, _, _} = F@2 ->
Expr@1 = {list, [F@2, {string, Esym}]},
eval_expr(Expr@1, Env);
Unhandable ->
l4u@sys_bridge_ffi:throw_err(
<<"unhandable exp in eval_expr"/utf8>>
),
{with_env, undefined, Env}
end;
_ ->
(true andalso erlang:element(3, erlang:element(7, Env))) andalso trace_set_last_expr(
Expr,
Env
),
{with_env, Expr, Env}
end.
-spec eval_funcall_args(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> {list(l4u@l4u_type:expr()),
l4u@l4u_type:env()}.
eval_funcall_args(Exprs, Env) ->
{Eargs, New_env} = eval_contents(Exprs, [], Env).
-spec local_continuation(
list(l4u@l4u_type:expr()),
l4u@l4u_type:env(),
l4u@l4u_type:env()
) -> l4u@l4u_type:expr().
local_continuation(Exprs, Local_env, Eval_env) ->
_assert_subject = eval(Exprs, undefined, Local_env),
{with_env, Rexpr, R_env} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"local_continuation"/utf8>>,
line => 864})
end,
{with_env, Rexpr, Eval_env}.
-spec continuation(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
continuation(Exprs, Local_env) ->
case true of
true ->
{continuation, Exprs, Local_env};
_ ->
eval(Exprs, undefined, Local_env)
end.
-spec bispform_def(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_def(Exprs, Env) ->
[{symbol, Sym}, Expr] = case Exprs of
[{symbol, _}, _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_def"/utf8>>,
line => 1412})
end,
_assert_subject = eval([Expr], undefined, Env),
{with_env, Eexpr, New_env} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_def"/utf8>>,
line => 1413})
end,
New_env@1 = env_set_global(New_env, Sym, Eexpr),
{with_env, Eexpr, New_env@1}.
-spec binds(l4u@l4u_type:env(), list(l4u@l4u_type:expr())) -> l4u@l4u_type:env().
binds(Eval_env, Bindings) ->
case Bindings of
[] ->
Eval_env;
[{symbol, Sym}, Expr | Rest] ->
_assert_subject = eval([Expr], undefined, Eval_env),
{with_env, Eexpr, Eval_env@1} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"binds"/utf8>>,
line => 1483})
end,
Eval_env@2 = env_set_local(Eval_env@1, Sym, Eexpr),
binds(Eval_env@2, Rest);
Unhandable ->
l4u@sys_bridge_ffi:throw_err(<<"unhandable bindings"/utf8>>),
Eval_env
end.
-spec bispform_let(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_let(Exprs, Env) ->
[First | Progn] = case Exprs of
[_ | _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_let"/utf8>>,
line => 1498})
end,
_assert_subject = uneval(First),
{list, Let_bindings} = case _assert_subject of
{list, _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_let"/utf8>>,
line => 1499})
end,
Let_env = Env,
Let_env@1 = binds(Let_env, Let_bindings),
New_local_vars = erlang:element(4, Let_env@1),
New_local_env = erlang:setelement(
5,
erlang:setelement(2, Let_env@1, erlang:element(2, Let_env@1)),
New_local_vars
),
local_continuation(Progn, New_local_env, Env).
-spec bispform_defmacro(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_defmacro(Exprs, Env) ->
[{symbol, Sym}, Expr] = case Exprs of
[{symbol, _}, _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_defmacro"/utf8>>,
line => 1589})
end,
_assert_subject = eval([Expr], undefined, Env),
{with_env, Eexpr, New_env} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_defmacro"/utf8>>,
line => 1590})
end,
Eexpr@1 = case Eexpr of
{macro, _, _, _, _} ->
Eexpr;
{closure, _, _, _, _} ->
closure_to_macro(Eexpr);
_ ->
l4u@sys_bridge_ffi:throw_err(<<"invalid macro"/utf8>>),
undefined
end,
New_env@1 = env_set_global(New_env, Sym, Eexpr@1),
{with_env, Eexpr@1, New_env@1}.
-spec bif_progn(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_progn(Exprs, Env) ->
continuation(Exprs, Env).
-spec bispform_if(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_if(Exprs, Env) ->
case Exprs of
[Condition, Then, Else_clause] ->
_assert_subject = eval([Condition], undefined, Env),
{with_env, Econdition, New_env} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_if"/utf8>>,
line => 1664})
end,
case is_true_condition(Econdition) of
true ->
continuation([Then], New_env);
false ->
continuation([Else_clause], New_env)
end;
[Condition@1, Then@1] ->
_assert_subject@1 = eval([Condition@1], undefined, Env),
{with_env, Econdition@1, New_env@1} = case _assert_subject@1 of
{with_env, _, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_if"/utf8>>,
line => 1672})
end,
case is_true_condition(Econdition@1) of
true ->
continuation([Then@1], New_env@1);
false ->
{with_env, nil, New_env@1}
end;
_ ->
l4u@sys_bridge_ffi:throw_err(<<"invalid if expression"/utf8>>),
{with_env, undefined, Env}
end.
-spec quasiquote_(l4u@l4u_type:expr(), l4u@l4u_type:env()) -> {list(l4u@l4u_type:expr()),
l4u@l4u_type:env()}.
quasiquote_(Expr, Env) ->
case Expr of
{list, Xs} ->
case Xs of
[Sym, Expr@1] when Sym =:= {symbol, <<"unquote"/utf8>>} ->
_assert_subject = eval([Expr@1], undefined, Env),
{with_env, Expr@2, Env@1} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"quasiquote_"/utf8>>,
line => 1977})
end,
{[Expr@2], Env@1};
[Sym@1, Expr@3] when Sym@1 =:= {symbol,
<<"splice-unquote"/utf8>>} ->
_assert_subject@1 = eval([Expr@3], undefined, Env),
{with_env, Eexpr, Env@2} = case _assert_subject@1 of
{with_env, _, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"quasiquote_"/utf8>>,
line => 1982})
end,
{get_contents(Eexpr), Env@2};
Exprs ->
{New_env@1, Lst} = gleam@list:fold(
Exprs,
{Env, []},
fun(State, X) ->
{Env@3, Acc} = State,
_assert_subject@2 = quasiquote_(X, Env@3),
{Exprs@1, New_env} = case _assert_subject@2 of
{_, _} -> _assert_subject@2;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@2,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"quasiquote_"/utf8>>,
line => 1989})
end,
{New_env, gleam@list:append(Acc, Exprs@1)}
end
),
{[make_container(Expr, Lst)], New_env@1}
end;
{vector, Xs} ->
case Xs of
[Sym, Expr@1] when Sym =:= {symbol, <<"unquote"/utf8>>} ->
_assert_subject = eval([Expr@1], undefined, Env),
{with_env, Expr@2, Env@1} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"quasiquote_"/utf8>>,
line => 1977})
end,
{[Expr@2], Env@1};
[Sym@1, Expr@3] when Sym@1 =:= {symbol,
<<"splice-unquote"/utf8>>} ->
_assert_subject@1 = eval([Expr@3], undefined, Env),
{with_env, Eexpr, Env@2} = case _assert_subject@1 of
{with_env, _, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"quasiquote_"/utf8>>,
line => 1982})
end,
{get_contents(Eexpr), Env@2};
Exprs ->
{New_env@1, Lst} = gleam@list:fold(
Exprs,
{Env, []},
fun(State, X) ->
{Env@3, Acc} = State,
_assert_subject@2 = quasiquote_(X, Env@3),
{Exprs@1, New_env} = case _assert_subject@2 of
{_, _} -> _assert_subject@2;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@2,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"quasiquote_"/utf8>>,
line => 1989})
end,
{New_env, gleam@list:append(Acc, Exprs@1)}
end
),
{[make_container(Expr, Lst)], New_env@1}
end;
_ ->
{[Expr], Env}
end.
-spec bispform_quasiquote(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_quasiquote(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_quasiquote"/utf8>>,
line => 2006})
end,
_assert_subject = quasiquote_(Expr, Env),
{[Eexpr], New_env} = case _assert_subject of
{[_], _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_quasiquote"/utf8>>,
line => 2007})
end,
{with_env, Eexpr, New_env}.
-spec bispform_quasiquote_expand(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_quasiquote_expand(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_quasiquote_expand"/utf8>>,
line => 2012})
end,
_assert_subject = quasiquote_(Expr, Env),
{[Eexpr], New_env} = case _assert_subject of
{[_], _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_quasiquote_expand"/utf8>>,
line => 2013})
end,
{with_env, Eexpr, New_env}.
-spec bif_eval(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_eval(Exprs, Env) ->
eval(Exprs, undefined, env_get_toplevel(Env)).
-spec apply(l4u@l4u_type:env(), l4u@l4u_type:expr(), list(l4u@l4u_type:expr())) -> l4u@l4u_type:expr().
apply(Env, Callable, Args) ->
eval([{list, gleam@list:append([Callable], Args)}], undefined, Env).
-spec apply_macro_(l4u@l4u_type:expr(), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
apply_macro_(Expr, Env) ->
case Expr of
{list, [{symbol, Callable} | Args] = Exprs} ->
case env_get(Env, Callable) of
{ok, {macro, _, _, _, _} = Macroval} ->
_assert_subject = apply(Env, Macroval, Args),
{with_env, New_expr, New_env} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"apply_macro_"/utf8>>,
line => 286})
end,
New_expr;
_ ->
{list,
gleam@list:map(
Exprs,
fun(E) -> apply_macro_(E, Env) end
)}
end;
X ->
X
end.
-spec apply_macro(l4u@l4u_type:expr(), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
apply_macro(Expr, Env) ->
Old = Expr,
New = apply_macro_(Expr, Env),
case Old =:= New of
true ->
New;
_ ->
apply_macro(New, Env)
end.
-spec apply_macro_1(l4u@l4u_type:expr(), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
apply_macro_1(Expr, Env) ->
case Expr of
{list, [{symbol, Callable} | Args] = Exprs} ->
case env_get(Env, Callable) of
{ok, {macro, _, _, _, _} = Macroval} ->
_assert_subject = apply(Env, Macroval, Args),
{with_env, New_expr, New_env} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"apply_macro_1"/utf8>>,
line => 305})
end,
New_expr;
_ ->
Expr
end;
X ->
X
end.
-spec macroexpand(l4u@l4u_type:env(), l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
macroexpand(Env, Ast) ->
case get_macro(Env, Ast) of
{ok, Macroval} ->
apply_macro_1(Macroval, Env);
_ ->
Ast
end.
-spec macroexpand_all(l4u@l4u_type:env(), l4u@l4u_type:expr()) -> l4u@l4u_type:expr().
macroexpand_all(Env, Ast) ->
case get_macro(Env, Ast) of
{ok, Macroval} ->
apply_macro(Macroval, Env);
_ ->
Ast
end.
-spec bispform_macroexpand(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_macroexpand(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_macroexpand"/utf8>>,
line => 2106})
end,
Expr@1 = macroexpand(Env, Expr),
{with_env, Expr@1, Env}.
-spec bispform_macroexpand_all(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_macroexpand_all(Exprs, Env) ->
[Expr] = case Exprs of
[_] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_macroexpand_all"/utf8>>,
line => 2112})
end,
Expr@1 = macroexpand_all(Env, Expr),
{with_env, Expr@1, Env}.
-spec funcall(
l4u@l4u_type:expr(),
list(l4u@l4u_type:expr()),
l4u@l4u_type:env()
) -> l4u@l4u_type:expr().
funcall(Callable, Eargs, New_env) ->
case Callable of
{bif, _, F} ->
F(Eargs, New_env);
{closure, Name, Params, Progn, Closure_env} ->
Bindings = bind_args(maps:from_list([]), Params, Eargs),
New_closure_env = generate_local_env(
<<"funcall"/utf8>>,
Closure_env,
Bindings,
erlang:element(5, New_env)
),
local_continuation(Progn, New_closure_env, New_env);
_ ->
l4u@sys_bridge_ffi:throw_err(<<"invalid function"/utf8>>),
undefined
end.
-spec bif_apply(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_apply(Exprs, Env) ->
[Callable | Rest_args] = case Exprs of
[_ | _] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_apply"/utf8>>,
line => 2198})
end,
_assert_subject = gleam@list:last(Rest_args),
{ok, Last_args} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_apply"/utf8>>,
line => 2199})
end,
_assert_subject@1 = uneval(Last_args),
{list, Last_args@1} = case _assert_subject@1 of
{list, _} -> _assert_subject@1;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@2,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_apply"/utf8>>,
line => 2201})
end,
{Args, _} = gleam@list:split(Rest_args, gleam@list:length(Rest_args) - 1),
Fnargs = gleam@list:concat([Args, Last_args@1]),
funcall(Callable, Fnargs, Env).
-spec bispform_try(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bispform_try(Exprs, Env) ->
Try_exprs = case Exprs of
_ -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_try"/utf8>>,
line => 2231})
end,
case gleam@list:last(Try_exprs) of
{ok,
{list,
[{symbol, <<"catch*"/utf8>>}, {symbol, Bind_to} | Catch_exprs]}} ->
Try_exprs@1 = gleam@list:take(
Try_exprs,
gleam@list:length(Try_exprs) - 1
),
Try_result = l4u@sys_bridge_ffi:catch_ex(
fun() ->
_assert_subject = eval(Try_exprs@1, undefined, Env),
{with_env, Ret_expr, New_env} = Res = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bispform_try"/utf8>>,
line => 2238})
end,
Res
end
),
case Try_result of
{ok, Result} ->
Result;
{error, Exexpr} ->
local_continuation(
Catch_exprs,
env_set_local(Env, Bind_to, Exexpr),
Env
)
end;
_ ->
eval(Try_exprs, undefined, Env)
end.
-spec rep(binary(), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
rep(Src, Env) ->
Result = eval(read(Src, Env), undefined, Env),
Result.
-spec bif_load_file(list(l4u@l4u_type:expr()), l4u@l4u_type:env()) -> l4u@l4u_type:expr().
bif_load_file(Exprs, Env) ->
[{string, Filename}] = case Exprs of
[{string, _}] -> Exprs;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_load_file"/utf8>>,
line => 2118})
end,
Contents = l4u@sys_bridge_ffi:load_file(Filename),
_assert_subject = rep(Contents, Env),
{with_env, _, New_env} = case _assert_subject of
{with_env, _, _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"bif_load_file"/utf8>>,
line => 2121})
end,
{with_env, nil, New_env}.
-spec generate_new_env(
l4u@l4u_type:p_dic(),
gleam@dict:dict(binary(), l4u@l4u_type:expr()),
list(binary())
) -> l4u@l4u_type:env().
generate_new_env(Pdic, Default_bindings, Init_files) ->
l4u@sys_bridge_ffi:process_dict_set(Pdic, <<"*trace_ip"/utf8>>, 0),
l4u@sys_bridge_ffi:process_dict_set(Pdic, <<"*trace_level"/utf8>>, 0),
_assert_subject = gleam@regex:compile(
<<"[\\s]*(~@|[\\[\\]{}()'`~^@]|\"(?:\\\\.|[^\\\\\"])*\"?|;.*|[^\\s\\[\\]{}('\"`,;)]*)"/utf8>>,
{options, false, false}
),
{ok, Regexp} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"generate_new_env"/utf8>>,
line => 2624})
end,
l4u@sys_bridge_ffi:process_dict_set(Pdic, <<"*regex"/utf8>>, Regexp),
Opts = {env_options, false, false},
Default_scopes = case true of
true ->
gleam@dict:map_values(
Default_bindings,
fun(K, V) -> l4u@sys_bridge_ffi:process_dict_set(Pdic, K, V) end
),
[{process_dict, Pdic}];
_ ->
[{process_dict, Pdic}, {scope, Default_bindings}]
end,
Env = {env,
{info, <<"toplevel"/utf8>>, 0},
Pdic,
maps:from_list([]),
maps:from_list([]),
Default_scopes,
Opts},
Env@2 = gleam@list:fold(
Init_files,
Env,
fun(Env@1, File) ->
true andalso begin
gleam@io:println(<<"- init "/utf8, File/binary>>),
true
end,
case l4u@sys_bridge_ffi:catch_ex(
fun() ->
Initialize = l4u@sys_bridge_ffi:load_file(File),
_assert_subject@1 = rep(Initialize, Env@1),
{with_env, _, New_env} = case _assert_subject@1 of
{with_env, _, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"l4u/l4u_core"/utf8>>,
function => <<"generate_new_env"/utf8>>,
line => 2673})
end,
New_env
end
) of
{ok, New_env@1} ->
New_env@1;
{error, Exexpr} ->
l4u@sys_bridge_ffi:dbgout2(
<<"init error:"/utf8>>,
l4u@sys_bridge_ffi:error_to_string(Exexpr, true)
),
Env@1
end
end
),
l4u@sys_bridge_ffi:process_dict_set(Pdic, <<"*toplevel*"/utf8>>, Env@2),
Env@2.
-spec make_new_l4u_core_env(
l4u@l4u_type:p_dic(),
list({binary(), l4u@l4u_type:expr()}),
list(binary())
) -> l4u@l4u_type:env().
make_new_l4u_core_env(Pdic, Bifs, Files) ->
Bif = fun(Name, F) -> {Name, {bif, description(Name), F}} end,
Bsf = fun(Name@1, F@1) -> {Name@1, {bispform, description(Name@1), F@1}} end,
Default_bindings = begin
_pipe = gleam@list:append(
[{<<"*host-language*"/utf8>>, {string, <<"gleam-erlang"/utf8>>}},
Bif(<<"+"/utf8>>, fun bif_add/2),
Bif(<<"-"/utf8>>, fun bif_sub/2),
Bif(<<"*"/utf8>>, fun bif_mul/2),
Bif(<<"/"/utf8>>, fun bif_div/2),
Bif(<<"mod"/utf8>>, fun bif_mod/2),
Bif(<<"="/utf8>>, fun bif_eqp/2),
Bif(<<"eq?"/utf8>>, fun bif_eqp/2),
Bif(<<"<"/utf8>>, fun bif_ltp/2),
Bif(<<">"/utf8>>, fun bif_gtp/2),
Bif(<<"<="/utf8>>, fun bif_lteqp/2),
Bif(<<">="/utf8>>, fun bif_gteqp/2),
Bif(<<"and"/utf8>>, fun bif_and/2),
Bif(<<"or"/utf8>>, fun bif_or/2),
Bif(<<"not"/utf8>>, fun bif_not/2),
Bsf(<<"def!"/utf8>>, fun bispform_def/2),
Bsf(<<"erase!"/utf8>>, fun bispform_erase/2),
Bif(<<"global-keys"/utf8>>, fun bif_global_keys/2),
Bif(<<"global-get"/utf8>>, fun bif_global_get/2),
Bsf(<<"let*"/utf8>>, fun bispform_let/2),
Bsf(<<"fn*"/utf8>>, fun bispform_fn/2),
Bsf(<<"macro*"/utf8>>, fun bispform_macro/2),
Bsf(<<"defmacro!"/utf8>>, fun bispform_defmacro/2),
Bif(<<"car"/utf8>>, fun bif_car/2),
Bif(<<"cdr"/utf8>>, fun bif_cdr/2),
Bif(<<"cons"/utf8>>, fun bif_cons/2),
Bsf(<<"do"/utf8>>, fun bif_progn/2),
Bsf(<<"if"/utf8>>, fun bispform_if/2),
Bif(<<"prn"/utf8>>, fun bif_prn/2),
Bif(<<"pr-str"/utf8>>, fun bif_pr_str/2),
Bif(<<"println"/utf8>>, fun bif_println/2),
Bif(<<"readline"/utf8>>, fun bif_readline/2),
Bif(<<"list"/utf8>>, fun bif_list/2),
Bif(<<"list?"/utf8>>, fun bif_listp/2),
Bif(<<"vec"/utf8>>, fun bif_vec/2),
Bif(<<"vector"/utf8>>, fun bif_vector/2),
Bif(<<"vector?"/utf8>>, fun bif_vectorp/2),
Bif(<<"to-hash-map"/utf8>>, fun bif_to_hash_map/2),
Bif(<<"hash-map"/utf8>>, fun bif_hash_map/2),
Bif(<<"hash-map?"/utf8>>, fun bif_hash_mapp/2),
Bif(<<"map?"/utf8>>, fun bif_hash_mapp/2),
Bif(<<"empty?"/utf8>>, fun bif_emptyp/2),
Bif(<<"nil?"/utf8>>, fun bif_nilp/2),
Bif(<<"true?"/utf8>>, fun bif_truep/2),
Bif(<<"false?"/utf8>>, fun bif_falsep/2),
Bif(<<"contains?"/utf8>>, fun bif_containsp/2),
Bif(<<"atom?"/utf8>>, fun bif_atomp/2),
Bif(<<"keyword"/utf8>>, fun bif_keyword/2),
Bif(<<"keyword?"/utf8>>, fun bif_keywordp/2),
Bif(<<"string?"/utf8>>, fun bif_stringp/2),
Bif(<<"number?"/utf8>>, fun bif_numberp/2),
Bif(<<"symbol"/utf8>>, fun bif_symbol/2),
Bif(<<"symbol?"/utf8>>, fun bif_symbolp/2),
Bif(<<"sequential?"/utf8>>, fun bif_sequentialp/2),
Bif(<<"fn?"/utf8>>, fun bif_fnp/2),
Bif(<<"macro?"/utf8>>, fun bif_macrop/2),
Bif(<<"count"/utf8>>, fun bif_count/2),
Bif(<<"atom"/utf8>>, fun bif_atom/2),
Bif(<<"deref"/utf8>>, fun bif_deref/2),
Bif(<<"reset!"/utf8>>, fun bif_reset/2),
Bsf(<<"quote"/utf8>>, fun bispform_quote/2),
Bsf(<<"quasiquote0"/utf8>>, fun bispform_quasiquote/2),
Bsf(<<"quasiquote"/utf8>>, fun bispform_quasiquote2/2),
Bsf(
<<"quasiquoteexpand0"/utf8>>,
fun bispform_quasiquote_expand/2
),
Bsf(
<<"quasiquoteexpand"/utf8>>,
fun bispform_quasiquote_expand2/2
),
Bsf(<<"macroexpand"/utf8>>, fun bispform_macroexpand/2),
Bsf(<<"macroexpand-all"/utf8>>, fun bispform_macroexpand_all/2),
Bif(<<"load-file"/utf8>>, fun bif_load_file/2),
Bif(<<"slurp"/utf8>>, fun bif_slurp/2),
Bif(<<"read-string"/utf8>>, fun bif_read_string/2),
Bif(<<"tokenize"/utf8>>, fun bif_tokenize/2),
Bif(<<"read"/utf8>>, fun bif_read/2),
Bif(<<"eval"/utf8>>, fun bif_eval/2),
Bif(<<"apply"/utf8>>, fun bif_apply/2),
Bsf(<<"try*"/utf8>>, fun bispform_try/2),
Bif(<<"throw"/utf8>>, fun bif_throw/2),
Bif(<<"meta"/utf8>>, fun bif_meta/2),
Bif(<<"with-meta"/utf8>>, fun bif_with_meta/2),
Bif(<<"assoc"/utf8>>, fun bif_assoc/2),
Bif(<<"dissoc"/utf8>>, fun bif_dissoc/2),
Bif(<<"get"/utf8>>, fun bif_get/2),
Bif(<<"keys"/utf8>>, fun bif_keys/2),
Bif(<<"vals"/utf8>>, fun bif_vals/2),
Bif(<<"gensym"/utf8>>, fun bif_gensym/2),
Bif(<<"time-ms"/utf8>>, fun bif_time_ms/2),
Bif(<<"str"/utf8>>, fun bif_str/2),
Bif(<<"show"/utf8>>, fun bif_show/2),
{<<"true"/utf8>>, true},
{<<"false"/utf8>>, false},
{<<"nil"/utf8>>, nil},
{<<"undefined"/utf8>>, undefined},
Bsf(<<"trace"/utf8>>, fun bif_trace/2),
Bsf(<<"trace-clear"/utf8>>, fun bif_trace_clear/2),
Bif(<<"inspect"/utf8>>, fun bif_inspect/2),
Bif(<<"inspect-env"/utf8>>, fun bif_inspect_env/2),
Bif(<<"describe"/utf8>>, fun bif_describe/2),
Bif(<<"def-custom-type"/utf8>>, fun bif_def_custom_type/2),
Bif(
<<"instanciate-custom-type"/utf8>>,
fun bif_instanciate_custom_type/2
),
Bif(<<"custom-type-to-map"/utf8>>, fun bif_custom_type_to_map/2)],
Bifs
),
maps:from_list(_pipe)
end,
Init_files = gleam@list:append(
[<<"default0.lisp"/utf8>>,
<<"default1.lisp"/utf8>>,
<<"prelude.lisp"/utf8>>],
Files
),
generate_new_env(Pdic, Default_bindings, Init_files).
-spec main() -> any().
main() ->
initialize(),
Pdic = l4u@sys_bridge_ffi:unique_pdic(),
Env = make_new_l4u_core_env(Pdic, [], []),
repl(Env, <<"stepA> "/utf8>>).