
Format fixes. Changed type of BLOCKHASH to variant. Fixed number of parameters to include target Changed op args Protected create Make new type store a SERIALIZED CODE (instead of RAW BYTECODE) Fix test Format Make create not protected format Fix serialization of fate_code type Align Add rebar3 Use shipped rebar3 Fix serialization, test Fix tests Rename fate_code to contract_bytearray Update README
148 lines
3.9 KiB
Plaintext
148 lines
3.9 KiB
Plaintext
%%% -*- erlang-indent-level:4; indent-tabs-mode: nil -*-
|
|
%%%-------------------------------------------------------------------
|
|
%%% @copyright (C) 2019, aeternity Anstalt
|
|
%%% @doc
|
|
%%% Handling FATE code.
|
|
%%% @end
|
|
%%% ###REPLACEWITHNOTE###
|
|
%%%-------------------------------------------------------------------
|
|
|
|
Definitions.
|
|
DIGIT = [0-9]
|
|
HEXDIGIT = [0-9a-fA-F]
|
|
LOWER = [a-z_]
|
|
UPPER = [A-Z]
|
|
BASE58 = [123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]
|
|
BASE64 = [A-Za-z0-9+/=]
|
|
INT = {DIGIT}+
|
|
HEX = 0x{HEXDIGIT}+
|
|
OBJ_PFX = (ak|ct|ok|oq|ch|sg)
|
|
OBJECT = @{OBJ_PFX}_{BASE58}+
|
|
CODE = @cb_{BASE64}+
|
|
BYTES = #{BASE64}+
|
|
WS = [\000-\s]
|
|
ID = {LOWER}[a-zA-Z0-9_]*
|
|
STRING = "[^"]*"
|
|
BITS = (\!)?\<[\s01]*\>
|
|
|
|
Rules.
|
|
arg{INT} : {token, {arg, TokenLine, parse_arg(TokenChars)}}.
|
|
var{INT} : {token, {var, TokenLine, parse_var(TokenChars)}}.
|
|
a : {token, {stack, TokenLine}}.
|
|
|
|
true : {token, {boolean, TokenLine, true}}.
|
|
false : {token, {boolean, TokenLine, false}}.
|
|
|
|
%% ###REPLACEWITHOPTOKENS###
|
|
|
|
FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}.
|
|
|
|
{BYTES} :
|
|
{token, {bytes, TokenLine, parse_hash(TokenChars)}}.
|
|
{CODE} :
|
|
{token, {contract_bytearray, TokenLine, parse_contract_bytearray(TokenChars)}}.
|
|
{OBJECT} :
|
|
{token, {object, TokenLine, parse_object(TokenChars)}}.
|
|
{ID} :
|
|
{token, {id, TokenLine, TokenChars}}.
|
|
{HEX} :
|
|
{token, {int, TokenLine, parse_hex(TokenChars)}}.
|
|
{INT} :
|
|
{token, {int, TokenLine, parse_int(TokenChars)}}.
|
|
-{INT} :
|
|
{token, {int, TokenLine, parse_int(TokenChars)}}.
|
|
|
|
%% Due to the definition of STRING the tokens start and end with a quote ".
|
|
{STRING} :
|
|
{token, {string, TokenLine, unicode:characters_to_binary(
|
|
lists:sublist(TokenChars, 2, length(TokenChars) - 2))}}.
|
|
{BITS} :
|
|
{token, {bits, TokenLine, bits(TokenChars)}}.
|
|
|
|
|
|
%% Symbols
|
|
\-\> : {token, {to, TokenLine}}.
|
|
\: : {token, {to, TokenLine}}.
|
|
|
|
\=\> : {token, {arrow, TokenLine}}.
|
|
\(\| : {token, {start_variant, TokenLine}}.
|
|
\|\) : {token, {end_variant, TokenLine}}.
|
|
|
|
, : {token, {',', TokenLine}}.
|
|
\( : {token, {'(', TokenLine}}.
|
|
\) : {token, {')', TokenLine}}.
|
|
\[ : {token, {'[', TokenLine}}.
|
|
\] : {token, {']', TokenLine}}.
|
|
\{ : {token, {'{', TokenLine}}.
|
|
\} : {token, {'}', TokenLine}}.
|
|
\| : {token, {'|', TokenLine}}.
|
|
\' : {token, {typerep, TokenLine}}.
|
|
|
|
;;.* :
|
|
{token, {comment, TokenLine, drop_prefix($;, TokenChars)}}.
|
|
|
|
\. : skip_token.
|
|
|
|
|
|
%% Whitespace ignore
|
|
{WS} : skip_token.
|
|
|
|
%% Comments (TODO: nested comments)
|
|
|
|
|
|
. : {error, "Unexpected token: " ++ TokenChars}.
|
|
|
|
Erlang code.
|
|
|
|
-export([scan/1]).
|
|
|
|
-dialyzer({nowarn_function, yyrev/2}).
|
|
|
|
-ignore_xref([format_error/1, string/2, token/2, token/3, tokens/2, tokens/3]).
|
|
|
|
-include_lib("aebytecode/include/aeb_fate_opcodes.hrl").
|
|
|
|
|
|
parse_hex("0x" ++ Chars) -> list_to_integer(Chars, 16).
|
|
|
|
parse_int(Chars) -> list_to_integer(Chars).
|
|
|
|
parse_arg("arg" ++ N) -> list_to_integer(N).
|
|
parse_var("var" ++ N) -> list_to_integer(N).
|
|
|
|
|
|
parse_hash("#" ++ Chars) ->
|
|
base64:decode(Chars).
|
|
|
|
parse_contract_bytearray("@" ++ Chars) ->
|
|
case aeser_api_encoder:decode(unicode:characters_to_binary(Chars)) of
|
|
{contract_bytearray, Bin} -> Bin
|
|
end.
|
|
|
|
parse_object([_|Chars]) ->
|
|
case aeser_api_encoder:decode(unicode:characters_to_binary(Chars)) of
|
|
{account_pubkey, Bin} -> {address, Bin};
|
|
{contract_pubkey, Bin} -> {contract, Bin};
|
|
{oracle_pubkey, Bin} -> {oracle, Bin};
|
|
{oracle_query_id, Bin} -> {oracle_query, Bin};
|
|
{channel, Bin} -> {channel, Bin};
|
|
{signature, Bin} -> {signature, Bin}
|
|
end.
|
|
|
|
scan(S) ->
|
|
string(S).
|
|
|
|
drop_prefix(C, [C|Rest]) ->
|
|
drop_prefix(C, Rest);
|
|
drop_prefix(_, Tail) -> Tail.
|
|
|
|
bits([$!, $< | Rest]) ->
|
|
bits(Rest, -1);
|
|
bits([$< | Rest]) ->
|
|
bits(Rest, 0).
|
|
|
|
bits([$> |_Rest], Acc) -> Acc;
|
|
bits([$0 | Rest], Acc) -> bits(Rest, Acc bsl 1);
|
|
bits([$1 | Rest], Acc) -> bits(Rest, (Acc bsl 1) bor 1);
|
|
bits([$ | Rest], Acc) -> bits(Rest, Acc).
|