Doc update for hz_sophia and hz_aaci and some minor fixes #30
+69
-10
@@ -4,26 +4,28 @@
|
||||
-copyright("Jarvis Carroll <spiveehere@gmail.com>").
|
||||
-license("GPL-3.0-or-later").
|
||||
|
||||
-export([parse_literal/1, parse_literal/2]).
|
||||
-export([parse_literal/2, parse_literal/1]).
|
||||
-export([fate_to_list/1, fate_to_list/2, fate_to_iolist/1, fate_to_iolist/2]).
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
|
||||
-spec parse_literal(Sophia) -> {ok, FATE} | {error, Reason}
|
||||
when Sophia :: string(),
|
||||
FATE :: gmb_fate_data:fate_type(),
|
||||
Reason :: term().
|
||||
|
||||
parse_literal(String) ->
|
||||
parse_literal(unknown_type(), String).
|
||||
|
||||
-spec parse_literal(Type, Sophia) -> {ok, FATE} | {error, Reason}
|
||||
when Type :: hz_aaci:annotated_type(),
|
||||
Sophia :: string(),
|
||||
FATE :: gmb_fate_data:fate_type(),
|
||||
Reason :: term().
|
||||
|
||||
%% @doc
|
||||
%% Parse a typed Sophia expression into a FATE term
|
||||
%% The Sophia expression must consist only of literals, thus making a 'Sophia
|
||||
%% term', which means no arithmetic, no function calls, no variables, etc.
|
||||
%% The FATE term is in the format that gmbytecode expects as input, for forming
|
||||
%% contract calls, etc. Used by the hz module to implement the 'sophia' format.
|
||||
%%
|
||||
%% The function takes type information retrieved from the AACI data structure,
|
||||
%% which is used to interpret record types and variant types, but is also used
|
||||
%% to check inputs and generate errors.
|
||||
|
||||
parse_literal(Type, String) ->
|
||||
case parse_expression(Type, {1, 1}, String) of
|
||||
{ok, {Result, NewPos, NewString}} ->
|
||||
@@ -43,6 +45,28 @@ parse_literal2(Result, Pos, String) ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
|
||||
-spec parse_literal(Sophia) -> {ok, FATE} | {error, Reason}
|
||||
when Sophia :: string(),
|
||||
FATE :: gmb_fate_data:fate_type(),
|
||||
Reason :: term().
|
||||
|
||||
%% @doc
|
||||
%% Parse an untyped Sophia expression into a FATE term
|
||||
%% Like parse_literal/2, but will not produce type errors. This function can
|
||||
%% still produce parsing errors, and can produce errors when variants or
|
||||
%% records are encountered, since they can't be parsed unless you have type
|
||||
%% information.
|
||||
%%
|
||||
%% Note that since records are implemented as tuples, if you are trying to call
|
||||
%a function that you know takes a record, but you don't have type information
|
||||
%% available in the context where the expression is being passed, then tuples
|
||||
%% can be used instead. This does not work if you have type information,
|
||||
%% though, as tuples and records are different Sophia/AACI types.
|
||||
|
||||
parse_literal(String) ->
|
||||
parse_literal(unknown_type(), String).
|
||||
|
||||
%%% Tokenizer
|
||||
|
||||
-define(IS_LATIN_UPPER(C), (((C) >= $A) and ((C) =< $Z))).
|
||||
@@ -927,6 +951,19 @@ wrap_error(Reason, _) -> Reason.
|
||||
when FATE :: gmb_fate_data:fate_type(),
|
||||
Sophia :: string().
|
||||
|
||||
%% @doc
|
||||
%% Print a FATE term from gmbytecode in Sophia syntax
|
||||
%% FATE terms usually come from using gmbytecode to decode the result of an
|
||||
%% on-chain transaction.
|
||||
%%
|
||||
%% This function does not use any type information to interpret the data, and
|
||||
%% so can make mistakes. It's okay for interpreting tuples, lists, maps,
|
||||
%% integers, and strings, but it will misinterpret the types of records and
|
||||
%% unicode characters, and will crash the process if variants are encountered.
|
||||
%%
|
||||
%% fate_to_list/2 should be used whenever possible, especially since
|
||||
%% transaction results are type checked by nodes at runtime.
|
||||
|
||||
fate_to_list(Term) ->
|
||||
fate_to_list(unknown_type(), Term).
|
||||
|
||||
@@ -935,10 +972,27 @@ fate_to_list(Term) ->
|
||||
FATE :: gmb_fate_data:fate_type(),
|
||||
Sophia :: string().
|
||||
|
||||
|
||||
%% @doc
|
||||
%% Print a FATE term from gmbytecode in Sophia syntax
|
||||
%% Like fate_to_list/1, but now type information from the AACI data structure
|
||||
%% can be provided, in order to correctly interpret types like records,
|
||||
%% variants, and unicode characters. If the type information you provide is
|
||||
%% incorrect for the FATE term provided, then the function will fall back to
|
||||
%% untyped pretty printing like in fate_to_list/1, but this is not recommended,
|
||||
%% as correct type information should always be available.
|
||||
|
||||
fate_to_list(Type, Term) ->
|
||||
IOList = fate_to_iolist(Type, Term),
|
||||
unicode:characters_to_list(IOList).
|
||||
|
||||
%% @doc
|
||||
%% Print a FATE term in Sophia syntax, without concatenating
|
||||
%% The fate_to_list/1 function builds an iolist, and then concatenates it into
|
||||
%% a list. If you are going to put the term into a bigger iolist directly
|
||||
%% after, or write it to a streaming device, then it can save effort and memory
|
||||
%% to just use the iolist directly.
|
||||
|
||||
-spec fate_to_iolist(FATE) -> Sophia
|
||||
when FATE :: gmb_fate_data:fate_type(),
|
||||
Sophia :: iolist().
|
||||
@@ -951,6 +1005,11 @@ fate_to_iolist(Term) ->
|
||||
FATE :: gmb_fate_data:fate_type(),
|
||||
Sophia :: iolist().
|
||||
|
||||
%% @doc
|
||||
%% Print a FATE term in Sophia syntax, without concatenating
|
||||
%% Prints using type information, like fate_to_list/2, but without spending
|
||||
%% time or memory concatenating the result into a list, like fate_to_iolist/1.
|
||||
|
||||
% Special case for singleton records, since they are erased during compilation.
|
||||
fate_to_iolist({_, _, {record, [{FieldName, FieldType}]}}, Term) ->
|
||||
singleton_record_to_iolist(FieldName, FieldType, Term);
|
||||
|
||||
Reference in New Issue
Block a user