typecheck bits
Sophia bitstrings aren't really something you initialize manually, so we have to make up a literal format for them. Failing that, we just accept arbitrary integers and bytearrays as bitstrings.
This commit is contained in:
parent
9bc0ffafd1
commit
78c9c67f38
@ -236,13 +236,13 @@ parse_expression(Type, Pos, String) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
parse_expression2(Type, Pos, String, {integer, _, Value, Row, Start, End}) ->
|
parse_expression2(Type, Pos, String, {integer, _, Value, Row, Start, End}) ->
|
||||||
case Type of
|
typecheck_integer(Type, Pos, String, Value, Row, Start, End);
|
||||||
{_, _, integer} ->
|
parse_expression2(Type, Pos, String, {character, "-", _, _, _, _}) ->
|
||||||
{ok, {Value, Pos, String}};
|
case next_token(Pos, String) of
|
||||||
{_, _, unknown_type} ->
|
{ok, {{integer, _, Value, Row, Start, End}, NewPos, NewString}} ->
|
||||||
{ok, {Value, Pos, String}};
|
typecheck_integer(Type, NewPos, NewString, -Value, Row, Start, End);
|
||||||
{O, N, _} ->
|
{error, Reason} ->
|
||||||
{error, {wrong_type, O, N, integer, Row, Start, End}}
|
{error, Reason}
|
||||||
end;
|
end;
|
||||||
parse_expression2(Type, Pos, String, {bytes, _, Value, Row, Start, End}) ->
|
parse_expression2(Type, Pos, String, {bytes, _, Value, Row, Start, End}) ->
|
||||||
Len = byte_size(Value),
|
Len = byte_size(Value),
|
||||||
@ -254,6 +254,10 @@ parse_expression2(Type, Pos, String, {bytes, _, Value, Row, Start, End}) ->
|
|||||||
{ok, {Result, Pos, String}};
|
{ok, {Result, Pos, String}};
|
||||||
{_, _, {bytes, [ExpectedLen]}} ->
|
{_, _, {bytes, [ExpectedLen]}} ->
|
||||||
{error, {bytes_wrong_size, ExpectedLen, Len, Row, Start, End}};
|
{error, {bytes_wrong_size, ExpectedLen, Len, Row, Start, End}};
|
||||||
|
{_, _, bits} ->
|
||||||
|
Size = bit_size(Value),
|
||||||
|
<<IntValue:Size>> = Value,
|
||||||
|
{ok, {{bits, IntValue}, Pos, String}};
|
||||||
{_, _, unknown_type} ->
|
{_, _, unknown_type} ->
|
||||||
{ok, {Result, Pos, String}};
|
{ok, {Result, Pos, String}};
|
||||||
{O, N, _} ->
|
{O, N, _} ->
|
||||||
@ -323,6 +327,10 @@ parse_alphanum(Type, Pos, String, ["true"], Row, Start, End) ->
|
|||||||
typecheck_bool(Type, Pos, String, true, Row, Start, End);
|
typecheck_bool(Type, Pos, String, true, Row, Start, End);
|
||||||
parse_alphanum(Type, Pos, String, ["false"], Row, Start, End) ->
|
parse_alphanum(Type, Pos, String, ["false"], Row, Start, End) ->
|
||||||
typecheck_bool(Type, Pos, String, false, Row, Start, End);
|
typecheck_bool(Type, Pos, String, false, Row, Start, End);
|
||||||
|
parse_alphanum(Type, Pos, String, ["Bits", "all"], Row, Start, End) ->
|
||||||
|
typecheck_bits(Type, Pos, String, -1, Row, Start, End);
|
||||||
|
parse_alphanum(Type, Pos, String, ["Bits", "none"], Row, Start, End) ->
|
||||||
|
typecheck_bits(Type, Pos, String, 0, Row, Start, End);
|
||||||
parse_alphanum(Type, Pos, String, [[C | _] = S], Row, Start, End) when ?IS_LATIN_LOWER(C) ->
|
parse_alphanum(Type, Pos, String, [[C | _] = S], Row, Start, End) when ?IS_LATIN_LOWER(C) ->
|
||||||
% From a programming perspective, we are trying to parse a constant, so
|
% From a programming perspective, we are trying to parse a constant, so
|
||||||
% an alphanum token can really only be a constructor, or a chain object.
|
% an alphanum token can really only be a constructor, or a chain object.
|
||||||
@ -350,6 +358,15 @@ parse_alphanum(Type, Pos, String, Path, Row, Start, End) ->
|
|||||||
% must be a variant constructor, or invalid.
|
% must be a variant constructor, or invalid.
|
||||||
parse_variant(Type, Pos, String, Path, Row, Start, End).
|
parse_variant(Type, Pos, String, Path, Row, Start, End).
|
||||||
|
|
||||||
|
typecheck_integer({_, _, integer}, Pos, String, Value, _, _, _) ->
|
||||||
|
{ok, {Value, Pos, String}};
|
||||||
|
typecheck_integer({_, _, unknown_type}, Pos, String, Value, _, _, _) ->
|
||||||
|
{ok, {Value, Pos, String}};
|
||||||
|
typecheck_integer({_, _, bits}, Pos, String, Value, _, _, _) ->
|
||||||
|
{ok, {{bits, Value}, Pos, String}};
|
||||||
|
typecheck_integer({O, N, _}, _, _, _, Row, Start, End) ->
|
||||||
|
{error, {wrong_type, O, N, integer, Row, Start, End}}.
|
||||||
|
|
||||||
typecheck_bool({_, _, unknown_type}, Pos, String, Value, _, _, _) ->
|
typecheck_bool({_, _, unknown_type}, Pos, String, Value, _, _, _) ->
|
||||||
{ok, {Value, Pos, String}};
|
{ok, {Value, Pos, String}};
|
||||||
typecheck_bool({_, _, boolean}, Pos, String, Value, _, _, _) ->
|
typecheck_bool({_, _, boolean}, Pos, String, Value, _, _, _) ->
|
||||||
@ -357,6 +374,13 @@ typecheck_bool({_, _, boolean}, Pos, String, Value, _, _, _) ->
|
|||||||
typecheck_bool({O, N, _}, _, _, _, Row, Start, End) ->
|
typecheck_bool({O, N, _}, _, _, _, Row, Start, End) ->
|
||||||
{error, {wrong_type, O, N, boolean, Row, Start, End}}.
|
{error, {wrong_type, O, N, boolean, Row, Start, End}}.
|
||||||
|
|
||||||
|
typecheck_bits({_, _, unknown_type}, Pos, String, Value, _, _, _) ->
|
||||||
|
{ok, {{bits, Value}, Pos, String}};
|
||||||
|
typecheck_bits({_, _, bits}, Pos, String, Value, _, _, _) ->
|
||||||
|
{ok, {{bits, Value}, Pos, String}};
|
||||||
|
typecheck_bits({O, N, _}, _, _, _, Row, Start, End) ->
|
||||||
|
{error, {wrong_type, O, N, bits, Row, Start, End}}.
|
||||||
|
|
||||||
typecheck_address({_, _, address}, Pos, String, Data, _, _, _) ->
|
typecheck_address({_, _, address}, Pos, String, Data, _, _, _) ->
|
||||||
{ok, {{address, Data}, Pos, String}};
|
{ok, {{address, Data}, Pos, String}};
|
||||||
typecheck_address({_, _, contract}, Pos, String, Data, _, _, _) ->
|
typecheck_address({_, _, contract}, Pos, String, Data, _, _, _) ->
|
||||||
@ -939,6 +963,7 @@ anon_types_test() ->
|
|||||||
% Integers.
|
% Integers.
|
||||||
check_parser("123"),
|
check_parser("123"),
|
||||||
check_parser("1_2_3"),
|
check_parser("1_2_3"),
|
||||||
|
check_parser("-123"),
|
||||||
% Booleans.
|
% Booleans.
|
||||||
check_parser("true"),
|
check_parser("true"),
|
||||||
check_parser("false"),
|
check_parser("false"),
|
||||||
@ -1038,6 +1063,15 @@ chain_objects_test() ->
|
|||||||
|
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
bits_test() ->
|
||||||
|
check_parser("Bits.all"),
|
||||||
|
check_parser("Bits.none"),
|
||||||
|
{_, Type} = compile_entrypoint_value_and_type("contract C = entrypoint f() = Bits.all", "f"),
|
||||||
|
check_sophia_to_fate(Type, "5", {bits, 5}),
|
||||||
|
check_sophia_to_fate(Type, "-5", {bits, -5}),
|
||||||
|
check_sophia_to_fate(Type, "#123", {bits, 256 + 32 + 3}),
|
||||||
|
ok.
|
||||||
|
|
||||||
singleton_records_test() ->
|
singleton_records_test() ->
|
||||||
TypeDef = "record singleton('a) = {it: 'a}",
|
TypeDef = "record singleton('a) = {it: 'a}",
|
||||||
check_parser_with_typedef(TypeDef, "{it = 123}"),
|
check_parser_with_typedef(TypeDef, "{it = 123}"),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user