Add hash, signature and object types.

This commit is contained in:
Erik Stenman 2019-03-14 16:45:10 +01:00
parent 34ae94e3e7
commit c614da15e0
6 changed files with 377 additions and 142 deletions

View File

@ -7,17 +7,29 @@
-define(FATE_MAP_T, #{ fate_type() => fate_type() }). -define(FATE_MAP_T, #{ fate_type() => fate_type() }).
-define(FATE_STRING_T, binary()). -define(FATE_STRING_T, binary()).
-define(FATE_ADDRESS_T, {address, <<_:256>>}). -define(FATE_ADDRESS_T, {address, <<_:256>>}).
-define(FATE_HASH_T, {hash, binary()}).
-define(FATE_SIGNATURE_T, {signature, binary()}).
-define(FATE_CONTRACT_T, {contract, <<_:256>>}).
-define(FATE_ORACLE_T, {oracle, <<_:256>>}).
-define(FATE_NAME_T, {name, <<_:256>>}).
-define(FATE_CHANNEL_T, {channel, <<_:256>>}).
-define(FATE_VARIANT_T, {variant, ?FATE_BYTE_T, ?FATE_BYTE_T, tuple()}). -define(FATE_VARIANT_T, {variant, ?FATE_BYTE_T, ?FATE_BYTE_T, tuple()}).
-define(FATE_VOID_T, void). -define(FATE_VOID_T, void).
-define(FATE_TUPLE_T, {tuple, tuple()}). -define(FATE_TUPLE_T, {tuple, tuple()}).
-define(FATE_BITS_T, {bits, integer()}). -define(FATE_BITS_T, {bits, integer()}).
-define(IS_FATE_INTEGER(X), is_integer(X)). -define(IS_FATE_INTEGER(X), (is_integer(X))).
-define(IS_FATE_LIST(X), (is_list(X))). -define(IS_FATE_LIST(X), (is_list(X))).
-define(IS_FATE_STRING(X), (is_binary(X))). -define(IS_FATE_STRING(X), (is_binary(X))).
-define(IS_FATE_MAP(X), (is_map(X))). -define(IS_FATE_MAP(X), (is_map(X))).
-define(IS_FATE_TUPLE(X), (is_tuple(X) andalso (tuple == element(1, X) andalso is_tuple(element(2, X))))). -define(IS_FATE_TUPLE(X), (is_tuple(X) andalso (tuple == element(1, X) andalso is_tuple(element(2, X))))).
-define(IS_FATE_ADDRESS(X), (is_tuple(X) andalso (address == element(1, X) andalso is_binary(element(2, X))))). -define(IS_FATE_ADDRESS(X), (is_tuple(X) andalso (address == element(1, X) andalso is_binary(element(2, X))))).
-define(IS_FATE_HASH(X), (is_tuple(X) andalso (hash == element(1, X) andalso is_binary(element(2, X))))).
-define(IS_FATE_SIGNATURE(X), (is_tuple(X) andalso (signature == element(1, X) andalso is_binary(element(2, X))))).
-define(IS_FATE_CONTRACT(X), (is_tuple(X) andalso (contract == element(1, X) andalso is_binary(element(2, X))))).
-define(IS_FATE_ORACLE(X), (is_tuple(X) andalso (oracle == element(1, X) andalso is_binary(element(2, X))))).
-define(IS_FATE_NAME(X), (is_tuple(X) andalso (name == element(1, X) andalso is_binary(element(2, X))))).
-define(IS_FATE_CHANNEL(X), (is_tuple(X) andalso (channel == element(1, X) andalso is_binary(element(2, X))))).
-define(IS_FATE_BITS(X), (is_tuple(X) andalso (bits == element(1, X) andalso is_integer(element(2, X))))). -define(IS_FATE_BITS(X), (is_tuple(X) andalso (bits == element(1, X) andalso is_integer(element(2, X))))).
-define(IS_FATE_VARIANT(X), (is_tuple(X) -define(IS_FATE_VARIANT(X), (is_tuple(X)
andalso andalso
@ -31,6 +43,12 @@
-define(FATE_UNIT, {tuple, {}}). -define(FATE_UNIT, {tuple, {}}).
-define(FATE_TUPLE(T), {tuple, T}). -define(FATE_TUPLE(T), {tuple, T}).
-define(FATE_ADDRESS(A), {address, A}). -define(FATE_ADDRESS(A), {address, A}).
-define(FATE_HASH(X), {hash, X}).
-define(FATE_SIGNATURE(S), {signature, S}).
-define(FATE_CONTRACT(X), {contract, X}).
-define(FATE_ORACLE(X), {oracle, X}).
-define(FATE_NAME(X), {name, X}).
-define(FATE_CHANNEL(X), {channel, X}).
-define(FATE_BITS(B), {bits, B}). -define(FATE_BITS(B), {bits, B}).
@ -38,6 +56,12 @@
-define(FATE_LIST_VALUE(X), (X)). -define(FATE_LIST_VALUE(X), (X)).
-define(FATE_STRING_VALUE(X), (X)). -define(FATE_STRING_VALUE(X), (X)).
-define(FATE_ADDRESS_VALUE(X), (element(2, X))). -define(FATE_ADDRESS_VALUE(X), (element(2, X))).
-define(FATE_HASH_VALUE(X), (element(2, X))).
-define(FATE_SIGNATURE_VALUE(X), (element(2, X))).
-define(FATE_CONTRACT_VALUE(X), (element(2, X))).
-define(FATE_ORACLE_VALUE(X), (element(2, X))).
-define(FATE_NAME_VALUE(X), (element(2, X))).
-define(FATE_CHANNEL_VALUE(X), (element(2, X))).
-define(FATE_MAP_VALUE(X), (X)). -define(FATE_MAP_VALUE(X), (X)).
-define(FATE_MAP_SIZE(X), (map_size(X))). -define(FATE_MAP_SIZE(X), (map_size(X))).
-define(FATE_STRING_SIZE(X), (byte_size(X))). -define(FATE_STRING_SIZE(X), (byte_size(X))).

View File

@ -40,9 +40,12 @@
%%% -2374683271468723648732648736498712634876147 %%% -2374683271468723648732648736498712634876147
%%% 1b. Integers as Hexadecimals:: 0x{Hexdigits} %%% 1b. Integers as Hexadecimals:: 0x{Hexdigits}
%%% 0x0deadbeef0 %%% 0x0deadbeef0
%%% 2. addresses, a base58 encoded string starting with #{base58char} %%% 2a. addresses, a base58 encoded string prefixed with @
%%% followed by up to 64 hex chars %%% @foo
%%% #00000deadbeef %%% 2b. contract addresse: ct_{base58char}+
%%% 2c. oracle addresse: ok_{base58char}+
%%% 2d. name addresse: nm_{base58char}+
%%% 2e. channel addresse: ch_{base58char}+
%%% 3. Boolean true or false %%% 3. Boolean true or false
%%% true %%% true
%%% false %%% false
@ -708,49 +711,16 @@ serialize_data(_, Data) ->
aeb_fate_encoding:serialize(Data). aeb_fate_encoding:serialize(Data).
serialize_signature({Args, RetType}) -> serialize_signature({Args, RetType}) ->
[serialize_type({tuple, Args}) | [aeb_fate_encoding:serialize_type({tuple, Args}) |
serialize_type(RetType)]. aeb_fate_encoding:serialize_type(RetType)].
deserialize_signature(Binary) -> deserialize_signature(Binary) ->
{{tuple, Args}, Rest} = deserialize_type(Binary), {{tuple, Args}, Rest} = aeb_fate_encoding:deserialize_type(Binary),
{RetType, Rest2} = deserialize_type(Rest), {RetType, Rest2} = aeb_fate_encoding:deserialize_type(Rest),
{{Args, RetType}, Rest2}. {{Args, RetType}, Rest2}.
deserialize_type(<<0, Rest/binary>>) -> {integer, Rest};
deserialize_type(<<1, Rest/binary>>) -> {boolean, Rest};
deserialize_type(<<2, Rest/binary>>) ->
{T, Rest2} = deserialize_type(Rest),
{{list, T}, Rest2};
deserialize_type(<<3, N, Rest/binary>>) ->
{Ts, Rest2} = deserialize_types(N, Rest, []),
{{tuple, Ts}, Rest2};
deserialize_type(<<4, Rest/binary>>) -> {address, Rest};
deserialize_type(<<5, Rest/binary>>) -> {bits, Rest};
deserialize_type(<<6, Rest/binary>>) ->
{K, Rest2} = deserialize_type(Rest),
{V, Rest3} = deserialize_type(Rest2),
{{map, K, V}, Rest3};
deserialize_type(<<7, Rest/binary>>) ->
{string, Rest};
deserialize_type(<<8, Size, Rest/binary>>) ->
{Variants, Rest2} = deserialize_variants(Size, Rest, []),
{{variant, Variants}, Rest2}.
deserialize_variants(0, Rest, Variants) ->
{lists:reverse(Variants), Rest};
deserialize_variants(N, Rest, Variants) ->
{T, Rest2} = deserialize_type(Rest),
deserialize_variants(N-1, Rest2, [T|Variants]).
deserialize_types(0, Binary, Acc) ->
{lists:reverse(Acc), Binary};
deserialize_types(N, Binary, Acc) ->
{T, Rest} = deserialize_type(Binary),
deserialize_types(N-1, Rest, [T | Acc]).
to_hexstring(ByteList) -> to_hexstring(ByteList) ->
@ -786,10 +756,41 @@ to_bytecode([{string,_line, String}|Rest], Address, Env, Code, Opts) ->
to_bytecode(Rest, Address, Env, to_bytecode(Rest, Address, Env,
[{immediate, aeb_fate_data:make_string(String)}|Code], [{immediate, aeb_fate_data:make_string(String)}|Code],
Opts); Opts);
to_bytecode([{address,_line, Value}|Rest], Address, Env, Code, Opts) -> to_bytecode([{address,_line, {address, Value}}|Rest],
Address, Env, Code, Opts) ->
to_bytecode(Rest, Address, Env, to_bytecode(Rest, Address, Env,
[{immediate, aeb_fate_data:make_address(Value)}|Code], [{immediate, aeb_fate_data:make_address(Value)}|Code],
Opts); Opts);
to_bytecode([{address,_line, {contract, Value}}|Rest],
Address, Env, Code, Opts) ->
to_bytecode(Rest, Address, Env,
[{immediate, aeb_fate_data:make_contract(Value)}|Code],
Opts);
to_bytecode([{address,_line, {oracle, Value}}|Rest],
Address, Env, Code, Opts) ->
to_bytecode(Rest, Address, Env,
[{immediate, aeb_fate_data:make_oracle(Value)}|Code],
Opts);
to_bytecode([{address,_line, {name, Value}}|Rest],
Address, Env, Code, Opts) ->
to_bytecode(Rest, Address, Env,
[{immediate, aeb_fate_data:make_name(Value)}|Code],
Opts);
to_bytecode([{address,_line, {channel, Value}}|Rest],
Address, Env, Code, Opts) ->
to_bytecode(Rest, Address, Env,
[{immediate, aeb_fate_data:make_contract(Value)}|Code],
Opts);
to_bytecode([{hash,_line, Value}|Rest],
Address, Env, Code, Opts) ->
to_bytecode(Rest, Address, Env,
[{immediate, aeb_fate_data:make_hash(Value)}|Code],
Opts);
to_bytecode([{signature,_line, Value}|Rest],
Address, Env, Code, Opts) ->
to_bytecode(Rest, Address, Env,
[{immediate, aeb_fate_data:make_signature(Value)}|Code],
Opts);
to_bytecode([{id,_line, ID}|Rest], Address, Env, Code, Opts) -> to_bytecode([{id,_line, ID}|Rest], Address, Env, Code, Opts) ->
{Hash, Env2} = insert_symbol(ID, Env), {Hash, Env2} = insert_symbol(ID, Env),
to_bytecode(Rest, Address, Env2, [{immediate, Hash}|Code], Opts); to_bytecode(Rest, Address, Env2, [{immediate, Hash}|Code], Opts);
@ -878,7 +879,6 @@ parse_variant([{start_variant,_line}
parse_value([{int,_line, Int} | Rest]) -> {Int, Rest}; parse_value([{int,_line, Int} | Rest]) -> {Int, Rest};
parse_value([{boolean,_line, Bool} | Rest]) -> {Bool, Rest}; parse_value([{boolean,_line, Bool} | Rest]) -> {Bool, Rest};
parse_value([{hash,_line, Hash} | Rest]) -> {Hash, Rest};
parse_value([{'{',_line} | Rest]) -> parse_map(Rest); parse_value([{'{',_line} | Rest]) -> parse_map(Rest);
parse_value([{'[',_line} | Rest]) -> parse_list(Rest); parse_value([{'[',_line} | Rest]) -> parse_list(Rest);
parse_value([{'(',_line} | Rest]) -> parse_value([{'(',_line} | Rest]) ->
@ -892,8 +892,20 @@ parse_value([{start_variant,_line}|_] = Tokens) ->
{Variant, Rest}; {Variant, Rest};
parse_value([{string,_line, String} | Rest]) -> parse_value([{string,_line, String} | Rest]) ->
{aeb_fate_data:make_string(String), Rest}; {aeb_fate_data:make_string(String), Rest};
parse_value([{address,_line, Address} | Rest]) -> parse_value([{address,_line, {address, Address}} | Rest]) ->
{aeb_fate_data:make_address(Address), Rest}. {aeb_fate_data:make_address(Address), Rest};
parse_value([{address,_line, {contract, Address}} | Rest]) ->
{aeb_fate_data:make_contract(Address), Rest};
parse_value([{address,_line, {oracle, Address}} | Rest]) ->
{aeb_fate_data:make_oracle(Address), Rest};
parse_value([{address,_line, {name, Address}} | Rest]) ->
{aeb_fate_data:make_name(Address), Rest};
parse_value([{address,_line, {channel, Address}} | Rest]) ->
{aeb_fate_data:make_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}.
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),
@ -917,6 +929,12 @@ to_type([{id, _, "integer"} | Rest]) -> {integer, Rest};
to_type([{id, _, "boolean"} | Rest]) -> {boolean, Rest}; to_type([{id, _, "boolean"} | Rest]) -> {boolean, Rest};
to_type([{id, _, "string"} | Rest]) -> {string, Rest}; to_type([{id, _, "string"} | Rest]) -> {string, Rest};
to_type([{id, _, "address"} | Rest]) -> {address, Rest}; to_type([{id, _, "address"} | Rest]) -> {address, Rest};
to_type([{id, _, "contract"} | Rest]) -> {contract, Rest};
to_type([{id, _, "oracle"} | Rest]) -> {oracle, Rest};
to_type([{id, _, "name"} | Rest]) -> {name, Rest};
to_type([{id, _, "channel"} | Rest]) -> {channel, Rest};
to_type([{id, _, "hash"} | Rest]) -> {hash, Rest};
to_type([{id, _, "signature"} | Rest]) -> {signature, Rest};
to_type([{id, _, "bits"} | Rest]) -> {bits, Rest}; to_type([{id, _, "bits"} | Rest]) -> {bits, Rest};
to_type([{'{', _}, {id, _, "list"}, {',', _} | Rest]) -> to_type([{'{', _}, {id, _, "list"}, {',', _} | Rest]) ->
%% TODO: Error handling %% TODO: Error handling
@ -951,25 +969,6 @@ to_list_of_types(Tokens) ->
{[Type], Rest} {[Type], Rest}
end. end.
-spec serialize_type(aeb_fate_data:fate_type_type()) -> [byte()].
serialize_type(integer) -> [0];
serialize_type(boolean) -> [1];
serialize_type({list, T}) -> [2 | serialize_type(T)];
serialize_type({tuple, Ts}) ->
case length(Ts) of
N when N =< 255 ->
[3, N | [serialize_type(T) || T <- Ts]]
end;
serialize_type(address) -> [4];
serialize_type(bits) -> [5];
serialize_type({map, K, V}) -> [6 | serialize_type(K) ++ serialize_type(V)];
serialize_type(string) -> [7];
serialize_type({variant, ListOfVariants}) ->
Size = length(ListOfVariants),
if Size < 256 ->
[8, Size | [serialize_type(T) || T <- ListOfVariants]]
end.
%% ------------------------------------------------------------------- %% -------------------------------------------------------------------
%% Helper functions %% Helper functions

View File

@ -4,7 +4,7 @@
%%% @doc %%% @doc
%%% Handling FATE code. %%% Handling FATE code.
%%% @end %%% @end
###REPLACEWITHNOTE### %%% ###REPLACEWITHNOTE###
%%%------------------------------------------------------------------- %%%-------------------------------------------------------------------
Definitions. Definitions.
@ -13,9 +13,13 @@ HEXDIGIT = [0-9a-fA-F]
LOWER = [a-z_] LOWER = [a-z_]
UPPER = [A-Z] UPPER = [A-Z]
BASE58 = [123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz] BASE58 = [123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]
BASE64 = [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy0123456789+/=]
INT = {DIGIT}+ INT = {DIGIT}+
HEX = 0x{HEXDIGIT}+ HEX = 0x{HEXDIGIT}+
HASH = #{BASE58}+ OBJECT = [a-z][a-z]_{BASE58}+
ADDRESS = @{BASE58}+
HASH = #{BASE64}+
SIG = \${BASE64}+
WS = [\000-\s] WS = [\000-\s]
ID = {LOWER}[a-zA-Z0-9_]* ID = {LOWER}[a-zA-Z0-9_]*
STRING = "[^"]*" STRING = "[^"]*"
@ -30,7 +34,7 @@ a{INT} : {token, {stack, TokenLine, parse_acc(TokenChars)}}.
true : {token, {boolean, TokenLine, true}}. true : {token, {boolean, TokenLine, true}}.
false : {token, {boolean, TokenLine, false}}. false : {token, {boolean, TokenLine, false}}.
###REPLACEWITHOPTOKENS### %% ###REPLACEWITHOPTOKENS###
FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}. FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}.
@ -43,7 +47,13 @@ FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}.
-{INT} : -{INT} :
{token, {int, TokenLine, parse_int(TokenChars)}}. {token, {int, TokenLine, parse_int(TokenChars)}}.
{HASH} : {HASH} :
{token, {address, TokenLine, parse_hash(TokenChars)}}. {token, {hash, TokenLine, parse_hash(TokenChars)}}.
{SIG} :
{token, {signature, TokenLine, parse_signature(TokenChars)}}.
{ADDRESS} :
{token, {address, TokenLine, {address, parse_address(TokenChars)}}}.
{OBJECT} :
{token, {object, TokenLine, parse_object(TokenChars)}}.
{STRING} : {STRING} :
{token, {string, TokenLine, list_to_binary(TokenChars)}}. {token, {string, TokenLine, list_to_binary(TokenChars)}}.
{BITS} : {BITS} :
@ -102,8 +112,26 @@ parse_acc("a" ++ N) -> list_to_integer(N).
parse_hash("#" ++ Chars) -> parse_hash("#" ++ Chars) ->
base64:decode(Chars).
parse_signature("$" ++ Chars) ->
base64:decode(Chars).
parse_address("@" ++ Chars) ->
base58_to_address(Chars). base58_to_address(Chars).
parse_object("ct_" ++ Chars) ->
{contract, base58_to_address(Chars)};
parse_object("ok_" ++ Chars) ->
{oracle, base58_to_address(Chars)};
parse_object("nm_" ++ Chars) ->
{name, base58_to_address(Chars)};
parse_object("ch_" ++ Chars) ->
{channel, base58_to_address(Chars)};
parse_object("ak_" ++ Chars) ->
{address, base58_to_address(Chars)}.
scan(S) -> scan(S) ->
string(S). string(S).

View File

@ -12,9 +12,13 @@
-type fate_map() :: ?FATE_MAP_T. -type fate_map() :: ?FATE_MAP_T.
-type fate_string() :: ?FATE_STRING_T. -type fate_string() :: ?FATE_STRING_T.
-type fate_address() :: ?FATE_ADDRESS_T. -type fate_address() :: ?FATE_ADDRESS_T.
-type fate_hash() :: ?FATE_HASH_T.
-type fate_contract() :: ?FATE_CONTRACT_T.
-type fate_oracle() :: ?FATE_ORACLE_T.
-type fate_name() :: ?FATE_NAME_T.
-type fate_channel() :: ?FATE_CHANNEL_T.
-type fate_signature() :: ?FATE_SIGNATURE_T.
-type fate_variant() :: ?FATE_VARIANT_T. -type fate_variant() :: ?FATE_VARIANT_T.
-type fate_tuple() :: ?FATE_TUPLE_T. -type fate_tuple() :: ?FATE_TUPLE_T.
-type fate_type_type() :: integer -type fate_type_type() :: integer
@ -23,6 +27,12 @@
| {map, fate_type(), fate_type()} | {map, fate_type(), fate_type()}
| {tuple, [fate_type()]} | {tuple, [fate_type()]}
| address | address
| hash
| signature
| contract
| oracle
| name
| channel
| bits | bits
| {variant, integer()}. | {variant, integer()}.
@ -36,6 +46,12 @@
| fate_tuple() | fate_tuple()
| fate_string() | fate_string()
| fate_address() | fate_address()
| fate_hash()
| fate_signature()
| fate_contract()
| fate_oracle()
| fate_name()
| fate_channel()
| fate_variant() | fate_variant()
| fate_map() | fate_map()
| fate_type_type(). | fate_type_type().
@ -49,6 +65,12 @@
, fate_tuple/0 , fate_tuple/0
, fate_string/0 , fate_string/0
, fate_address/0 , fate_address/0
, fate_hash/0
, fate_signature/0
, fate_contract/0
, fate_oracle/0
, fate_name/0
, fate_channel/0
, fate_variant/0 , fate_variant/0
, fate_map/0 , fate_map/0
, fate_type_type/0 , fate_type_type/0
@ -62,6 +84,12 @@
, make_string/1 , make_string/1
, make_map/1 , make_map/1
, make_address/1 , make_address/1
, make_hash/1
, make_signature/1
, make_contract/1
, make_oracle/1
, make_name/1
, make_channel/1
, make_bits/1 , make_bits/1
, make_unit/0 , make_unit/0
, tuple_to_list/1 , tuple_to_list/1
@ -71,19 +99,26 @@
-export([format/1]). -export([format/1]).
make_integer(I) when is_integer(I) -> ?MAKE_FATE_INTEGER(I).
make_boolean(true) -> ?FATE_TRUE; make_boolean(true) -> ?FATE_TRUE;
make_boolean(false) -> ?FATE_FALSE. make_boolean(false) -> ?FATE_FALSE.
make_list([]) -> ?FATE_NIL; make_list([]) -> ?FATE_NIL;
make_list(L) -> ?MAKE_FATE_LIST(L). make_list(L) -> ?MAKE_FATE_LIST(L).
make_string(S) when is_list(S) ->
?FATE_STRING(list_to_binary(lists:flatten(S)));
make_string(S) when is_binary(S) -> ?FATE_STRING(S).
make_unit() -> ?FATE_UNIT. make_unit() -> ?FATE_UNIT.
make_tuple(T) -> ?FATE_TUPLE(T). make_tuple(T) -> ?FATE_TUPLE(T).
make_map(M) -> ?MAKE_FATE_MAP(M). make_map(M) -> ?MAKE_FATE_MAP(M).
make_address(A) -> ?FATE_ADDRESS(A). make_address(X) -> ?FATE_ADDRESS(X).
make_hash(X) -> ?FATE_HASH(X).
make_signature(X) -> ?FATE_SIGNATURE(X).
make_contract(X) -> ?FATE_CONTRACT(X).
make_oracle(X) -> ?FATE_ORACLE(X).
make_name(X) -> ?FATE_NAME(X).
make_channel(X) -> ?FATE_CHANNEL(X).
make_integer(I) when is_integer(I) -> ?MAKE_FATE_INTEGER(I).
make_bits(I) when is_integer(I) -> ?FATE_BITS(I). make_bits(I) when is_integer(I) -> ?FATE_BITS(I).
make_string(S) when is_list(S) ->
?FATE_STRING(list_to_binary(lists:flatten(S)));
make_string(S) when is_binary(S) -> ?FATE_STRING(S).
make_variant(Size, Tag, Values) when is_integer(Size), is_integer(Tag) make_variant(Size, Tag, Values) when is_integer(Size), is_integer(Tag)
, 0 =< Size , 0 =< Size
@ -103,6 +138,22 @@ encode({bits, Term}) when is_integer(Term) -> make_bits(Term);
encode({address, B}) when is_binary(B) -> make_address(B); encode({address, B}) when is_binary(B) -> make_address(B);
encode({address, I}) when is_integer(I) -> B = <<I:256>>, make_address(B); encode({address, I}) when is_integer(I) -> B = <<I:256>>, make_address(B);
encode({address, S}) when is_list(S) -> make_address(base58_to_address(S)); encode({address, S}) when is_list(S) -> make_address(base58_to_address(S));
encode({hash, H}) when is_binary(H) -> make_hash(H);
encode({hash, H}) when is_list(H) -> make_hash(base64:decode(H));
encode({signature, S}) when is_binary(S) -> make_signature(S);
encode({signature, S}) when is_list(S) -> make_signature(base64:decode(S));
encode({contract, B}) when is_binary(B) -> make_contract(B);
encode({contract, I}) when is_integer(I) -> B = <<I:256>>, make_contract(B);
encode({contract, S}) when is_list(S) -> make_contract(base58_to_address(S));
encode({oracle, B}) when is_binary(B) -> make_oracle(B);
encode({oracle, I}) when is_integer(I) -> B = <<I:256>>, make_oracle(B);
encode({oracle, S}) when is_list(S) -> make_oracle(base58_to_address(S));
encode({name, B}) when is_binary(B) -> make_name(B);
encode({name, I}) when is_integer(I) -> B = <<I:256>>, make_name(B);
encode({name, S}) when is_list(S) -> make_name(base58_to_address(S));
encode({channel, B}) when is_binary(B) -> make_channel(B);
encode({channel, I}) when is_integer(I) -> B = <<I:256>>, make_channel(B);
encode({channel, S}) when is_list(S) -> make_channel(base58_to_address(S));
encode({variant, Size, Tag, Values}) -> make_variant(Size, Tag, Values); encode({variant, Size, Tag, Values}) -> make_variant(Size, Tag, Values);
encode(Term) when is_integer(Term) -> make_integer(Term); encode(Term) when is_integer(Term) -> make_integer(Term);
encode(Term) when is_boolean(Term) -> make_boolean(Term); encode(Term) when is_boolean(Term) -> make_boolean(Term);
@ -120,6 +171,12 @@ decode(?FATE_TRUE) -> true;
decode(?FATE_FALSE) -> false; decode(?FATE_FALSE) -> false;
decode(L) when ?IS_FATE_LIST(L) -> [decode(E) || E <- L]; decode(L) when ?IS_FATE_LIST(L) -> [decode(E) || E <- L];
decode(?FATE_ADDRESS(<<Address:256>>)) -> {address, Address}; decode(?FATE_ADDRESS(<<Address:256>>)) -> {address, Address};
decode(?FATE_HASH(H)) -> {hash, H};
decode(?FATE_SIGNATURE(S)) -> {signature, S};
decode(?FATE_CONTRACT(X)) -> {contract, X};
decode(?FATE_ORACLE(X)) -> {oracle, X};
decode(?FATE_NAME(X)) -> {name, X};
decode(?FATE_CHANNEL(X)) -> {channel, X};
decode(?FATE_BITS(Bits)) -> {bits, Bits}; decode(?FATE_BITS(Bits)) -> {bits, Bits};
decode(?FATE_TUPLE(T)) -> erlang:list_to_tuple([decode(E) || E <- T]); decode(?FATE_TUPLE(T)) -> erlang:list_to_tuple([decode(E) || E <- T]);
decode(?FATE_VARIANT(Size, Tag, Values)) -> {variant, Size, Tag, Values}; decode(?FATE_VARIANT(Size, Tag, Values)) -> {variant, Size, Tag, Values};
@ -148,7 +205,13 @@ format(?FATE_VARIANT(Size, Tag, T)) ->
" |)"]; " |)"];
format(M) when ?IS_FATE_MAP(M) -> format(M) when ?IS_FATE_MAP(M) ->
["{ ", format_kvs(maps:to_list(?FATE_MAP_VALUE(M))), " }"]; ["{ ", format_kvs(maps:to_list(?FATE_MAP_VALUE(M))), " }"];
format(?FATE_ADDRESS(Address)) -> ["#", address_to_base58(Address)]; format(?FATE_ADDRESS(Address)) -> [address_to_base58(Address)];
format(?FATE_HASH(X)) -> ["#", base64:encode(X)];
format(?FATE_SIGNATURE(X)) -> ["$", base64:encode(X)];
format(?FATE_CONTRACT(X)) -> ["ct_", address_to_base58(X)];
format(?FATE_ORACLE(X)) -> ["ok_", address_to_base58(X)];
format(?FATE_NAME(X)) -> ["nm_", address_to_base58(X)];
format(?FATE_CHANNEL(X)) -> ["ch_", address_to_base58(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

@ -37,7 +37,9 @@
-export([ deserialize/1 -export([ deserialize/1
, deserialize_one/1 , deserialize_one/1
, deserialize_type/1
, serialize/1 , serialize/1
, serialize_type/1
]). ]).
-include("aeb_fate_data.hrl"). -include("aeb_fate_data.hrl").
@ -47,28 +49,44 @@
-define(SMALL_INT , 2#0). %% sxxxxxx 0 - 6 bit integer with sign bit -define(SMALL_INT , 2#0). %% sxxxxxx 0 - 6 bit integer with sign bit
%% 1 Set below %% 1 Set below
-define(LONG_STRING , 2#00000001). %% 000000 01 - RLP encoded array, size >= 64 -define(LONG_STRING , 2#00000001). %% 000000 01 | RLP encoded array - when size >= 64
-define(SHORT_STRING , 2#01). %% xxxxxx 01 - [bytes], 0 < xxxxxx:size < 64 -define(SHORT_STRING , 2#01). %% xxxxxx 01 | [bytes] - when 0 < xxxxxx:size < 64
%% 11 Set below %% 11 Set below
-define(SHORT_LIST , 2#0011). %% xxxx 0011 - [encoded elements], 0 < length < 16 -define(SHORT_LIST , 2#0011). %% xxxx 0011 | [encoded elements] when 0 < length < 16
%% xxxx 0111 - FREE (For typedefs in future) %% xxxx 0111
-define(LONG_TUPLE , 2#00001011). %% 0000 1011 - RLP encoded (size - 16) + [encoded elements], -define(TYPE_INTEGER , 2#00000111). %% 0000 0111 - Integer typedef
-define(SHORT_TUPLE , 2#1011). %% xxxx 1011 - [encoded elements], 0 < size < 16 -define(TYPE_BOOLEAN , 2#00010111). %% 0001 0111 - Boolean typedef
-define(TYPE_LIST , 2#00100111). %% 0010 0111 | Type
-define(TYPE_TUPLE , 2#00110111). %% 0011 0111 | Size | [Element Types]
-define(TYPE_OBJECT , 2#01000111). %% 0100 0111 | ObjectType
-define(TYPE_BITS , 2#01010111). %% 0101 0111 - Bits typedef
-define(TYPE_MAP , 2#01100111). %% 0110 0111 | Type | Type
-define(TYPE_STRING , 2#01110111). %% 0111 0111 - string typedef
-define(TYPE_VARIANT , 2#10000111). %% 1000 0111 | Size | [Type]
%% 1001 0111
%% 1010 0111
%% 1011 0111
%% 1100 0111
%% 1101 0111
%% 1110 0111
%% 1111 0111
-define(LONG_TUPLE , 2#00001011). %% 0000 1011 | RLP encoded (size - 16) | [encoded elements],
-define(SHORT_TUPLE , 2#1011). %% xxxx 1011 | [encoded elements] when 0 < size < 16
%% 1111 Set below %% 1111 Set below
-define(LONG_LIST , 2#00011111). %% 0001 1111 - RLP encoded (length - 16) + [Elements] -define(LONG_LIST , 2#00011111). %% 0001 1111 | RLP encoded (length - 16) | [encoded lements]
-define(MAP , 2#00101111). %% 0010 1111 - RLP encoded size + [encoded key, encoded value] -define(MAP , 2#00101111). %% 0010 1111 | RLP encoded size | [encoded key, encoded value]
-define(EMPTY_TUPLE , 2#00111111). %% 0011 1111 -define(EMPTY_TUPLE , 2#00111111). %% 0011 1111
-define(POS_BITS , 2#01001111). %% 0100 1111 - RLP encoded integer (to be interpreted as bitfield) -define(POS_BITS , 2#01001111). %% 0100 1111 | RLP encoded integer (to be interpreted as bitfield)
-define(EMPTY_STRING , 2#01011111). %% 0101 1111 -define(EMPTY_STRING , 2#01011111). %% 0101 1111
-define(POS_BIG_INT , 2#01101111). %% 0110 1111 - RLP encoded (integer - 64) -define(POS_BIG_INT , 2#01101111). %% 0110 1111 | RLP encoded (integer - 64)
-define(FALSE , 2#01111111). %% 0111 1111 -define(FALSE , 2#01111111). %% 0111 1111
%% %% 1000 1111 - FREE (Possibly for bytecode in the future.) %% %% 1000 1111 - FREE (Possibly for bytecode in the future.)
-define(ADDRESS , 2#10011111). %% 1001 1111 - [32 bytes] -define(OBJECT , 2#10011111). %% 1001 1111 | ObjectType | RLP encoded Array
-define(VARIANT , 2#10101111). %% 1010 1111 - encoded size + encoded tag + encoded values -define(VARIANT , 2#10101111). %% 1010 1111 | encoded size | encoded tag | [encoded values]
-define(NIL , 2#10111111). %% 1011 1111 - Empty list -define(NIL , 2#10111111). %% 1011 1111 - Empty list
-define(NEG_BITS , 2#11001111). %% 1100 1111 - RLP encoded integer (infinite 1:s bitfield) -define(NEG_BITS , 2#11001111). %% 1100 1111 | RLP encoded integer (infinite 1:s bitfield)
-define(EMPTY_MAP , 2#11011111). %% 1101 1111 -define(EMPTY_MAP , 2#11011111). %% 1101 1111
-define(NEG_BIG_INT , 2#11101111). %% 1110 1111 - RLP encoded (integer - 64) -define(NEG_BIG_INT , 2#11101111). %% 1110 1111 | RLP encoded (integer - 64)
-define(TRUE , 2#11111111). %% 1111 1111 -define(TRUE , 2#11111111). %% 1111 1111
-define(SHORT_TUPLE_SIZE, 16). -define(SHORT_TUPLE_SIZE, 16).
@ -79,6 +97,14 @@
-define(POS_SIGN, 0). -define(POS_SIGN, 0).
-define(NEG_SIGN, 1). -define(NEG_SIGN, 1).
%% Object types
-define(OTYPE_ADDRESS, 0).
-define(OTYPE_HASH, 1).
-define(OTYPE_SIGNATURE, 2).
-define(OTYPE_CONTRACT, 3).
-define(OTYPE_ORACLE, 4).
-define(OTYPE_NAME, 5).
-define(OTYPE_CHANNEL, 6).
%% -------------------------------------------------- %% --------------------------------------------------
%% Serialize %% Serialize
@ -106,7 +132,19 @@ serialize(String) when ?IS_FATE_STRING(String),
Bytes = ?FATE_STRING_VALUE(String), Bytes = ?FATE_STRING_VALUE(String),
<<?LONG_STRING, (aeser_rlp:encode(Bytes))/binary>>; <<?LONG_STRING, (aeser_rlp:encode(Bytes))/binary>>;
serialize(?FATE_ADDRESS(Address)) when is_binary(Address) -> serialize(?FATE_ADDRESS(Address)) when is_binary(Address) ->
<<?ADDRESS, (aeser_rlp:encode(Address))/binary>>; <<?OBJECT, ?OTYPE_ADDRESS, (aeser_rlp:encode(Address))/binary>>;
serialize(?FATE_HASH(Address)) when is_binary(Address) ->
<<?OBJECT, ?OTYPE_HASH, (aeser_rlp:encode(Address))/binary>>;
serialize(?FATE_SIGNATURE(Address)) when is_binary(Address) ->
<<?OBJECT, ?OTYPE_SIGNATURE, (aeser_rlp:encode(Address))/binary>>;
serialize(?FATE_CONTRACT(Address)) when is_binary(Address) ->
<<?OBJECT, ?OTYPE_CONTRACT, (aeser_rlp:encode(Address))/binary>>;
serialize(?FATE_ORACLE(Address)) when is_binary(Address) ->
<<?OBJECT, ?OTYPE_ORACLE, (aeser_rlp:encode(Address))/binary>>;
serialize(?FATE_NAME(Address)) when is_binary(Address) ->
<<?OBJECT, ?OTYPE_NAME, (aeser_rlp:encode(Address))/binary>>;
serialize(?FATE_CHANNEL(Address)) when is_binary(Address) ->
<<?OBJECT, ?OTYPE_CHANNEL, (aeser_rlp:encode(Address))/binary>>;
serialize(?FATE_TUPLE(T)) when size(T) > 0 -> serialize(?FATE_TUPLE(T)) when size(T) > 0 ->
S = size(T), S = size(T),
L = tuple_to_list(T), L = tuple_to_list(T),
@ -142,6 +180,79 @@ serialize(?FATE_VARIANT(Size, Tag, Values)) when 0 < Size, Size < 256,
(serialize(?FATE_TUPLE(Values)))/binary (serialize(?FATE_TUPLE(Values)))/binary
>>. >>.
%% -----------------------------------------------------
-spec serialize_type(aeb_fate_data:fate_type_type()) -> [byte()].
serialize_type(integer) -> [?TYPE_INTEGER];
serialize_type(boolean) -> [?TYPE_BOOLEAN];
serialize_type({list, T}) -> [?TYPE_LIST | serialize_type(T)];
serialize_type({tuple, Ts}) ->
case length(Ts) of
N when N =< 255 ->
[?TYPE_TUPLE, N | [serialize_type(T) || T <- Ts]]
end;
serialize_type(address) -> [?TYPE_OBJECT, ?OTYPE_ADDRESS];
serialize_type(hash) -> [?TYPE_OBJECT, ?OTYPE_HASH];
serialize_type(signature) -> [?TYPE_OBJECT, ?OTYPE_SIGNATURE];
serialize_type(contract) -> [?TYPE_OBJECT, ?OTYPE_CONTRACT];
serialize_type(oracle) -> [?TYPE_OBJECT, ?OTYPE_ORACLE];
serialize_type(name) -> [?TYPE_OBJECT, ?OTYPE_NAME];
serialize_type(channel) -> [?TYPE_OBJECT, ?OTYPE_CHANNEL];
serialize_type(bits) -> [?TYPE_BITS];
serialize_type({map, K, V}) -> [?TYPE_MAP
| serialize_type(K) ++ serialize_type(V)];
serialize_type(string) -> [?TYPE_STRING];
serialize_type({variant, ListOfVariants}) ->
Size = length(ListOfVariants),
if Size < 256 ->
[?TYPE_VARIANT, Size | [serialize_type(T) || T <- ListOfVariants]]
end.
-spec deserialize_type(binary()) -> {aeb_fate_data:fate_type_type(), binary()}.
deserialize_type(<<?TYPE_INTEGER, Rest/binary>>) -> {integer, Rest};
deserialize_type(<<?TYPE_BOOLEAN, Rest/binary>>) -> {boolean, Rest};
deserialize_type(<<?TYPE_LIST, Rest/binary>>) ->
{T, Rest2} = deserialize_type(Rest),
{{list, T}, Rest2};
deserialize_type(<<?TYPE_TUPLE, N, Rest/binary>>) ->
{Ts, Rest2} = deserialize_types(N, Rest, []),
{{tuple, Ts}, Rest2};
deserialize_type(<<TYPE_OBJECT, ObjectType, Rest/binary>>) ->
case ObjectType of
?OTYPE_ADDRESS -> {address, Rest};
?OTYPE_HASH -> {hash, Rest};
?OTYPE_SIGNATURE -> {signature, Rest};
?OTYPE_CONTRACT -> {contract, Rest};
?OTYPE_ORACLE -> {oracle, Rest};
?OTYPE_NAME -> {name, Rest};
?OTYPE_CHANNEL -> {channel, Rest}
end;
deserialize_type(<<?TYPE_BITS, Rest/binary>>) -> {bits, Rest};
deserialize_type(<<?TYPE_MAP, Rest/binary>>) ->
{K, Rest2} = deserialize_type(Rest),
{V, Rest3} = deserialize_type(Rest2),
{{map, K, V}, Rest3};
deserialize_type(<<?TYPE_STRING, Rest/binary>>) ->
{string, Rest};
deserialize_type(<<?TYPE_VARIANT, Size, Rest/binary>>) ->
{Variants, Rest2} = deserialize_variants(Size, Rest, []),
{{variant, Variants}, Rest2}.
deserialize_variants(0, Rest, Variants) ->
{lists:reverse(Variants), Rest};
deserialize_variants(N, Rest, Variants) ->
{T, Rest2} = deserialize_type(Rest),
deserialize_variants(N-1, Rest2, [T|Variants]).
deserialize_types(0, Binary, Acc) ->
{lists:reverse(Acc), Binary};
deserialize_types(N, Binary, Acc) ->
{T, Rest} = deserialize_type(Binary),
deserialize_types(N-1, Rest, [T | Acc]).
%% ----------------------------------------------------- %% -----------------------------------------------------
@ -205,9 +316,19 @@ deserialize2(<<S:6, ?SHORT_STRING:2, Rest/binary>>) ->
String = binary:part(Rest, 0, S), String = binary:part(Rest, 0, S),
Rest2 = binary:part(Rest, byte_size(Rest), - (byte_size(Rest) - S)), Rest2 = binary:part(Rest, byte_size(Rest), - (byte_size(Rest) - S)),
{?MAKE_FATE_STRING(String), Rest2}; {?MAKE_FATE_STRING(String), Rest2};
deserialize2(<<?ADDRESS, Rest/binary>>) -> deserialize2(<<?OBJECT, ObjectType, Rest/binary>>) ->
{A, Rest2} = aeser_rlp:decode_one(Rest), {A, Rest2} = aeser_rlp:decode_one(Rest),
{?FATE_ADDRESS(A), Rest2}; Val =
case ObjectType of
?OTYPE_ADDRESS -> ?FATE_ADDRESS(A);
?OTYPE_HASH -> ?FATE_HASH(A);
?OTYPE_SIGNATURE -> ?FATE_SIGNATURE(A);
?OTYPE_CONTRACT -> ?FATE_CONTRACT(A);
?OTYPE_ORACLE -> ?FATE_ORACLE(A);
?OTYPE_NAME -> ?FATE_NAME(A);
?OTYPE_CHANNEL -> ?FATE_CHANNEL(A)
end,
{Val, Rest2};
deserialize2(<<?TRUE, Rest/binary>>) -> deserialize2(<<?TRUE, Rest/binary>>) ->
{?FATE_TRUE, Rest}; {?FATE_TRUE, Rest};
deserialize2(<<?FALSE, Rest/binary>>) -> deserialize2(<<?FALSE, Rest/binary>>) ->

View File

@ -393,9 +393,9 @@ gen_token(#{opname := OpName}) ->
io_lib:format("~-28s: {token, {mnemonic, TokenLine, ~w}}.\n", io_lib:format("~-28s: {token, {mnemonic, TokenLine, ~w}}.\n",
[Name, OpName]). [Name, OpName]).
insert_tokens_in_template(<<"###REPLACEWITHOPTOKENS###", Rest/binary >>, Tokens) -> insert_tokens_in_template(<<"%% ###REPLACEWITHOPTOKENS###", Rest/binary >>, Tokens) ->
[Tokens, Rest]; [Tokens, Rest];
insert_tokens_in_template(<<"###REPLACEWITHNOTE###", Rest/binary >>, Tokens) -> insert_tokens_in_template(<<"%%% ###REPLACEWITHNOTE###", Rest/binary >>, Tokens) ->
[ [
"%%%\n" "%%%\n"
"%%% === === N O T E : This file is generated do not edit. === ===\n" "%%% === === N O T E : This file is generated do not edit. === ===\n"