From 2357813f49c3de64d3a3f984111a2b804a0dc40c Mon Sep 17 00:00:00 2001 From: Tobias Lindahl Date: Fri, 7 Jun 2019 13:09:54 +0200 Subject: [PATCH] Introduce typereps --- include/aeb_fate_data.hrl | 3 ++- src/aeb_fate_asm.erl | 8 +++++++- src/aeb_fate_asm_scan.template | 1 + src/aeb_fate_data.erl | 4 ++++ src/aeb_fate_encoding.erl | 21 +++++++++++++++++++-- 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/include/aeb_fate_data.hrl b/include/aeb_fate_data.hrl index 6218244..db11d0b 100644 --- a/include/aeb_fate_data.hrl +++ b/include/aeb_fate_data.hrl @@ -39,6 +39,7 @@ andalso is_tuple(element(4, 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_TUPLE(T), {tuple, T}). @@ -50,7 +51,7 @@ -define(FATE_NAME(X), {name, X}). -define(FATE_CHANNEL(X), {channel, X}). -define(FATE_BITS(B), {bits, B}). - +-define(FATE_TYPEREP(T), {typerep, T}). -define(FATE_INTEGER_VALUE(X), (X)). -define(FATE_BOOLEAN_VALUE(X), (X)). diff --git a/src/aeb_fate_asm.erl b/src/aeb_fate_asm.erl index e9d70ee..82de00b 100644 --- a/src/aeb_fate_asm.erl +++ b/src/aeb_fate_asm.erl @@ -304,6 +304,10 @@ to_bytecode([{start_variant,_line}|_] = Tokens, Address, Env, Code, Opts) -> {Arities, Tag, Values, Rest} = parse_variant(Tokens), Variant = aeb_fate_data:make_variant(Arities, Tag, Values), 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(Rest, Address, Env, [{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]) -> {aeb_fate_data:make_hash(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]) -> {ArgsType, [{'to', _} | Rest2]} = to_arg_types(Rest), diff --git a/src/aeb_fate_asm_scan.template b/src/aeb_fate_asm_scan.template index bd67d28..ec7a6e8 100644 --- a/src/aeb_fate_asm_scan.template +++ b/src/aeb_fate_asm_scan.template @@ -75,6 +75,7 @@ FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}. \{ : {token, {'{', TokenLine}}. \} : {token, {'}', TokenLine}}. \| : {token, {'|', TokenLine}}. +\' : {token, {typerep, TokenLine}}. ;;.* : {token, {comment, TokenLine, drop_prefix($;, TokenChars)}}. diff --git a/src/aeb_fate_data.erl b/src/aeb_fate_data.erl index 1b6f6ae..7567dfb 100644 --- a/src/aeb_fate_data.erl +++ b/src/aeb_fate_data.erl @@ -95,6 +95,7 @@ , make_channel/1 , make_bits/1 , make_unit/0 + , make_typerep/1 ]). -export([ elt/2 @@ -122,6 +123,7 @@ make_bits(I) when is_integer(I) -> ?FATE_BITS(I). make_string(S) when is_list(S) -> ?FATE_STRING(iolist_to_binary(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) %% 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)]; format(?FATE_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_bits(0, Acc) -> Acc; diff --git a/src/aeb_fate_encoding.erl b/src/aeb_fate_encoding.erl index c324124..f58779f 100644 --- a/src/aeb_fate_encoding.erl +++ b/src/aeb_fate_encoding.erl @@ -115,6 +115,18 @@ -define(OTYPE_NAME, 5). -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 %% 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 >> end - end. + end; +serialize(?FATE_TYPEREP(T)) -> + iolist_to_binary(serialize_type(T)). %% ----------------------------------------------------- @@ -424,7 +438,10 @@ deserialize2(<>) -> true -> {?FATE_VARIANT(Arities, Tag, T), Rest3} end - end. + end; +deserialize2(<> = Bin) when ?IS_TYPE_TAG(TypeTag) -> + {Type, Rest} = deserialize_type(Bin), + {?FATE_TYPEREP(Type), Rest}. insert_kv([]) -> []; insert_kv([K, V | R]) -> [{K, V} | insert_kv(R)].