Introduce typereps

This commit is contained in:
Tobias Lindahl 2019-06-07 13:09:54 +02:00
parent b45509962e
commit 2357813f49
5 changed files with 33 additions and 4 deletions

View File

@ -39,6 +39,7 @@
andalso is_tuple(element(4, X)) andalso is_tuple(element(4, X))
))). ))).
-define(IS_FATE_BOOLEAN(X), is_boolean(X)). -define(IS_FATE_BOOLEAN(X), is_boolean(X)).
-define(IS_FATE_TYPEREP(X), (is_tuple(X) andalso tuple_size(X) =:= 2 andalso element(1, X) =:= typerep)).
-define(FATE_UNIT, {tuple, {}}). -define(FATE_UNIT, {tuple, {}}).
-define(FATE_TUPLE(T), {tuple, T}). -define(FATE_TUPLE(T), {tuple, T}).
@ -50,7 +51,7 @@
-define(FATE_NAME(X), {name, X}). -define(FATE_NAME(X), {name, X}).
-define(FATE_CHANNEL(X), {channel, X}). -define(FATE_CHANNEL(X), {channel, X}).
-define(FATE_BITS(B), {bits, B}). -define(FATE_BITS(B), {bits, B}).
-define(FATE_TYPEREP(T), {typerep, T}).
-define(FATE_INTEGER_VALUE(X), (X)). -define(FATE_INTEGER_VALUE(X), (X)).
-define(FATE_BOOLEAN_VALUE(X), (X)). -define(FATE_BOOLEAN_VALUE(X), (X)).

View File

@ -304,6 +304,10 @@ to_bytecode([{start_variant,_line}|_] = Tokens, Address, Env, Code, Opts) ->
{Arities, Tag, Values, Rest} = parse_variant(Tokens), {Arities, Tag, Values, Rest} = parse_variant(Tokens),
Variant = aeb_fate_data:make_variant(Arities, Tag, Values), Variant = aeb_fate_data:make_variant(Arities, Tag, Values),
to_bytecode(Rest, Address, Env, [{immediate, Variant}|Code], Opts); to_bytecode(Rest, Address, Env, [{immediate, Variant}|Code], Opts);
to_bytecode([{typerep,_line}|Rest], Address, Env, Code, Opts) ->
{Type, Rest1} = to_type(Rest),
TypeRep = aeb_fate_data:make_typerep(Type),
to_bytecode(Rest1, Address, Env, [{immediate, TypeRep}|Code], Opts);
to_bytecode([{bits,_line, Bits}|Rest], Address, Env, Code, Opts) -> to_bytecode([{bits,_line, Bits}|Rest], Address, Env, Code, Opts) ->
to_bytecode(Rest, Address, Env, to_bytecode(Rest, Address, Env,
[{immediate, aeb_fate_data:make_bits(Bits)}|Code], Opts); [{immediate, aeb_fate_data:make_bits(Bits)}|Code], Opts);
@ -403,7 +407,9 @@ parse_value([{object,_line, {channel, Address}} | Rest]) ->
parse_value([{hash,_line, Hash} | Rest]) -> parse_value([{hash,_line, Hash} | Rest]) ->
{aeb_fate_data:make_hash(Hash), Rest}; {aeb_fate_data:make_hash(Hash), Rest};
parse_value([{signature,_line, Hash} | Rest]) -> parse_value([{signature,_line, Hash} | Rest]) ->
{aeb_fate_data:make_signature(Hash), Rest}. {aeb_fate_data:make_signature(Hash), Rest};
parse_value([{typerep,_line} | Rest]) ->
to_type(Rest).
to_fun_def([{id, _, Name}, {'(', _} | Rest]) -> to_fun_def([{id, _, Name}, {'(', _} | Rest]) ->
{ArgsType, [{'to', _} | Rest2]} = to_arg_types(Rest), {ArgsType, [{'to', _} | Rest2]} = to_arg_types(Rest),

View File

@ -75,6 +75,7 @@ FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}.
\{ : {token, {'{', TokenLine}}. \{ : {token, {'{', TokenLine}}.
\} : {token, {'}', TokenLine}}. \} : {token, {'}', TokenLine}}.
\| : {token, {'|', TokenLine}}. \| : {token, {'|', TokenLine}}.
\' : {token, {typerep, TokenLine}}.
;;.* : ;;.* :
{token, {comment, TokenLine, drop_prefix($;, TokenChars)}}. {token, {comment, TokenLine, drop_prefix($;, TokenChars)}}.

View File

@ -95,6 +95,7 @@
, make_channel/1 , make_channel/1
, make_bits/1 , make_bits/1
, make_unit/0 , make_unit/0
, make_typerep/1
]). ]).
-export([ -export([
elt/2 elt/2
@ -122,6 +123,7 @@ make_bits(I) when is_integer(I) -> ?FATE_BITS(I).
make_string(S) when is_list(S) -> make_string(S) when is_list(S) ->
?FATE_STRING(iolist_to_binary(S)); ?FATE_STRING(iolist_to_binary(S));
make_string(S) when is_binary(S) -> ?FATE_STRING(S). make_string(S) when is_binary(S) -> ?FATE_STRING(S).
make_typerep(T) -> ?FATE_TYPEREP(T).
%% Tag points to the selected variant (zero based) %% Tag points to the selected variant (zero based)
%% The arity of this variant is read from the list of provided arities %% The arity of this variant is read from the list of provided arities
@ -177,6 +179,8 @@ format(?FATE_NAME(X)) ->
["@", aeser_api_encoder:encode(name, X)]; ["@", aeser_api_encoder:encode(name, X)];
format(?FATE_CHANNEL(X)) -> format(?FATE_CHANNEL(X)) ->
["@", aeser_api_encoder:encode(channel, X)]; ["@", aeser_api_encoder:encode(channel, X)];
format(?FATE_TYPEREP(X)) ->
["'", io_lib:format("~p", [X])];
format(V) -> exit({not_a_fate_type, V}). format(V) -> exit({not_a_fate_type, V}).
format_bits(0, Acc) -> Acc; format_bits(0, Acc) -> Acc;

View File

@ -115,6 +115,18 @@
-define(OTYPE_NAME, 5). -define(OTYPE_NAME, 5).
-define(OTYPE_CHANNEL, 6). -define(OTYPE_CHANNEL, 6).
-define(IS_TYPE_TAG(X), (X =:= ?TYPE_INTEGER orelse
X =:= ?TYPE_BOOLEAN orelse
X =:= ?TYPE_ANY orelse
X =:= ?TYPE_VAR orelse
X =:= ?TYPE_LIST orelse
X =:= ?TYPE_TUPLE orelse
X =:= ?TYPE_OBJECT orelse
X =:= ?TYPE_BITS orelse
X =:= ?TYPE_MAP orelse
X =:= ?TYPE_STRING orelse
X =:= ?TYPE_VARIANT)).
%% -------------------------------------------------- %% --------------------------------------------------
%% Serialize %% Serialize
%% Serialized a Fate data value into a sequence of bytes %% Serialized a Fate data value into a sequence of bytes
@ -200,7 +212,9 @@ serialize(?FATE_VARIANT(Arities, Tag, Values)) ->
(serialize(?FATE_TUPLE(Values)))/binary (serialize(?FATE_TUPLE(Values)))/binary
>> >>
end end
end. end;
serialize(?FATE_TYPEREP(T)) ->
iolist_to_binary(serialize_type(T)).
%% ----------------------------------------------------- %% -----------------------------------------------------
@ -424,7 +438,10 @@ deserialize2(<<?VARIANT, Rest/binary>>) ->
true -> true ->
{?FATE_VARIANT(Arities, Tag, T), Rest3} {?FATE_VARIANT(Arities, Tag, T), Rest3}
end end
end. end;
deserialize2(<<TypeTag, _/binary>> = Bin) when ?IS_TYPE_TAG(TypeTag) ->
{Type, Rest} = deserialize_type(Bin),
{?FATE_TYPEREP(Type), Rest}.
insert_kv([]) -> []; insert_kv([]) -> [];
insert_kv([K, V | R]) -> [{K, V} | insert_kv(R)]. insert_kv([K, V | R]) -> [{K, V} | insert_kv(R)].