Parse all types of values except variants.
This commit is contained in:
parent
1c7436edab
commit
d78b78e494
@ -48,14 +48,15 @@
|
||||
%%% false
|
||||
%%% 5. Strings
|
||||
%%% "Hello"
|
||||
%%% 6. Empty map
|
||||
%%% 6. Map
|
||||
%%% {}
|
||||
%%% { 1 => { "foo" => true, "bar" => false}
|
||||
%%% 7. Lists
|
||||
%%% []
|
||||
%%% [1, 2]
|
||||
%%% 8. Bit field
|
||||
%%% <000>
|
||||
%%% <1010>
|
||||
%%% <1010 1010>
|
||||
%%% <>
|
||||
%%% !<>
|
||||
%%% 9. Tuples
|
||||
@ -569,7 +570,11 @@ 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}.
|
||||
{{map, K, V}, Rest3};
|
||||
deserialize_type(<<7, Rest/binary>>) ->
|
||||
{string, Rest}.
|
||||
|
||||
|
||||
|
||||
deserialize_types(0, Binary, Acc) ->
|
||||
{lists:reverse(Acc), Binary};
|
||||
@ -616,6 +621,19 @@ to_bytecode([{hash,_line, Hash}|Rest], Address, Env, Code, Opts) ->
|
||||
to_bytecode([{id,_line, ID}|Rest], Address, Env, Code, Opts) ->
|
||||
{Hash, Env2} = insert_symbol(ID, Env),
|
||||
to_bytecode(Rest, Address, Env2, [{immediate, Hash}|Code], Opts);
|
||||
to_bytecode([{'{',_line}|Rest], Address, Env, Code, Opts) ->
|
||||
{Map, Rest2} = parse_map(Rest),
|
||||
to_bytecode(Rest2, Address, Env, [{immediate, Map}|Code], Opts);
|
||||
to_bytecode([{'[',_line}|Rest], Address, Env, Code, Opts) ->
|
||||
{List, Rest2} = parse_list(Rest),
|
||||
to_bytecode(Rest2, Address, Env, [{immediate, List}|Code], Opts);
|
||||
to_bytecode([{'(',_line}|Rest], Address, Env, Code, Opts) ->
|
||||
{Elements, Rest2} = parse_tuple(Rest),
|
||||
Tuple = aeb_fate_data:make_tuple(list_to_tuple(Elements)),
|
||||
to_bytecode(Rest2, Address, Env, [{immediate, Tuple}|Code], Opts);
|
||||
to_bytecode([{bits,_line, Bits}|Rest], Address, Env, Code, Opts) ->
|
||||
to_bytecode(Rest, Address, Env, [{immediate, Bits}|Code], Opts);
|
||||
|
||||
to_bytecode([{comment, Line, Comment}|Rest], Address, Env, Code, Opts) ->
|
||||
Env2 = insert_annotation(comment, Line, Comment, Env),
|
||||
to_bytecode(Rest, Address, Env2, Code, Opts);
|
||||
@ -632,6 +650,51 @@ to_bytecode([], Address, Env, Code, Opts) ->
|
||||
end,
|
||||
Env2.
|
||||
|
||||
parse_map([{'}',_line}|Rest]) ->
|
||||
{#{}, Rest};
|
||||
parse_map(Tokens) ->
|
||||
{Key, [{arrow, _} | Rest]} = parse_value(Tokens),
|
||||
{Value, Rest2} = parse_value(Rest),
|
||||
case Rest2 of
|
||||
[{',',_} | Rest3] ->
|
||||
{Map, Rest4} = parse_map(Rest3),
|
||||
{Map#{Key => Value}, Rest4};
|
||||
[{'}',_} | Rest3] ->
|
||||
{#{Key => Value}, Rest3}
|
||||
end.
|
||||
|
||||
parse_list([{']',_line}|Rest]) ->
|
||||
{[], Rest};
|
||||
parse_list(Tokens) ->
|
||||
{Head , Rest} = parse_value(Tokens),
|
||||
case Rest of
|
||||
[{',',_} | Rest2] ->
|
||||
{Tail, Rest3} = parse_list(Rest2),
|
||||
{[Head | Tail], Rest3};
|
||||
[{']',_} | Rest3] ->
|
||||
{[Head], Rest3}
|
||||
end.
|
||||
|
||||
parse_tuple([{')',_line}|Rest]) ->
|
||||
{[], Rest};
|
||||
parse_tuple(Tokens) ->
|
||||
{Head , Rest} = parse_value(Tokens),
|
||||
case Rest of
|
||||
[{',',_} | Rest2] ->
|
||||
{Tail, Rest3} = parse_tuple(Rest2),
|
||||
{[Head | Tail], Rest3};
|
||||
[{')',_} | Rest3] ->
|
||||
{[Head], Rest3}
|
||||
end.
|
||||
|
||||
|
||||
parse_value([{int,_line, Int} | Rest]) -> {Int, 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_list(Rest);
|
||||
parse_value([{'(',_line} | Rest]) -> parse_tuple(Rest).
|
||||
|
||||
|
||||
to_fun_def([{id, _, Name}, {'(', _} | Rest]) ->
|
||||
{ArgsType, [{'to', _} | Rest2]} = to_arg_types(Rest),
|
||||
@ -689,9 +752,11 @@ serialize_type({tuple, Ts}) ->
|
||||
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(address) -> [4];
|
||||
serialize_type(bits) -> [5];
|
||||
serialize_type({map, K, V}) -> [6 | serialize_type(K) ++ serialize_type(V)];
|
||||
serialize_type(string) -> [7].
|
||||
|
||||
|
||||
|
||||
%% -------------------------------------------------------------------
|
||||
|
@ -17,7 +17,8 @@ HEX = 0x{HEXDIGIT}+
|
||||
HASH = #{HEXDIGIT}+
|
||||
WS = [\000-\s]
|
||||
ID = {LOWER}[a-zA-Z0-9_]*
|
||||
|
||||
STRING = "[^"]*"
|
||||
BITS = (\!)?\<[\s01]*\>
|
||||
|
||||
Rules.
|
||||
arg{INT} : {token, {arg, TokenLine, parse_arg(TokenChars)}}.
|
||||
@ -38,13 +39,22 @@ FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}.
|
||||
{token, {int, TokenLine, parse_hex(TokenChars)}}.
|
||||
{INT} :
|
||||
{token, {int, TokenLine, parse_int(TokenChars)}}.
|
||||
-{INT} :
|
||||
{token, {int, TokenLine, parse_int(TokenChars)}}.
|
||||
{HASH} :
|
||||
{token, {hash, TokenLine, parse_hash(TokenChars)}}.
|
||||
{STRING} :
|
||||
{token, {hash, TokenLine, list_to_binary(TokenChars)}}.
|
||||
{BITS} :
|
||||
{token, {bits, TokenLine, bits(TokenChars)}}.
|
||||
|
||||
|
||||
%% Symbols
|
||||
\-\> : {token, {'to', TokenLine}}.
|
||||
\: : {token, {'to', TokenLine}}.
|
||||
\-\> : {token, {to, TokenLine}}.
|
||||
\: : {token, {to, TokenLine}}.
|
||||
|
||||
\=\> : {token, {arrow, TokenLine}}.
|
||||
|
||||
, : {token, {',', TokenLine}}.
|
||||
\( : {token, {'(', TokenLine}}.
|
||||
\) : {token, {')', TokenLine}}.
|
||||
@ -97,3 +107,13 @@ scan(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).
|
||||
|
@ -128,7 +128,7 @@ serialize(L) when ?IS_FATE_LIST(L) ->
|
||||
<<?LONG_LIST, Val/binary, Rest/binary>>
|
||||
end;
|
||||
serialize(Map) when ?IS_FATE_MAP(Map) ->
|
||||
L = [{_K,_V}|_] = maps:to_list(?FATE_MAP_VALUE(Map)),
|
||||
L = [{_K,_V}|_] = lists:sort(maps:to_list(?FATE_MAP_VALUE(Map))),
|
||||
Size = length(L),
|
||||
%% TODO: check all K same type, and all V same type
|
||||
%% check K =/= map
|
||||
|
@ -50,6 +50,8 @@ sources() ->
|
||||
, "remote"
|
||||
, "test"
|
||||
, "tuple"
|
||||
, "mapofmap"
|
||||
, "immediates"
|
||||
].
|
||||
|
||||
check_roundtrip(File) ->
|
||||
@ -62,4 +64,5 @@ check_roundtrip(File) ->
|
||||
{_Env2, ByteCode2} = assemble(DissasmCode),
|
||||
Code1 = aeb_fate_asm:strip(ByteCode),
|
||||
Code2 = aeb_fate_asm:strip(ByteCode2),
|
||||
io:format("~s~n", [aeb_fate_asm:to_asm(disassemble(ByteCode2))]),
|
||||
?assertEqual(Code1, Code2).
|
||||
|
68
test/asm_code/immediates.fate
Normal file
68
test/asm_code/immediates.fate
Normal file
@ -0,0 +1,68 @@
|
||||
;; CONTRACT immediates
|
||||
|
||||
FUNCTION integer() : integer
|
||||
RETURNR 42
|
||||
|
||||
FUNCTION neg_integer() : integer
|
||||
RETURNR -2374683271468723648732648736498712634876147
|
||||
|
||||
FUNCTION hex_integer() : integer
|
||||
RETURNR 0x0deadbeef0
|
||||
|
||||
FUNCTION bool() : boolean
|
||||
RETURNR true
|
||||
|
||||
FUNCTION bool_f() : boolean
|
||||
RETURNR false
|
||||
|
||||
FUNCTION string() : string
|
||||
RETURNR "Hello"
|
||||
|
||||
FUNCTION map() : {map, integer, boolean}
|
||||
RETURNR {}
|
||||
|
||||
FUNCTION map2() : {map, integer, boolean}
|
||||
RETURNR {1 => true}
|
||||
|
||||
FUNCTION map3() : {map, integer, boolean}
|
||||
RETURNR {1 => true,
|
||||
2 => false}
|
||||
|
||||
FUNCTION map4() : {map, integer, {map, string, boolean}}
|
||||
RETURNR {1 => { "foo" => true, "bar" => false},
|
||||
2 => {},
|
||||
3 => { "foo" => false}}
|
||||
|
||||
FUNCTION nil() : {list, integer}
|
||||
RETURNR []
|
||||
|
||||
FUNCTION list1() : {list, integer}
|
||||
RETURNR [1]
|
||||
|
||||
FUNCTION list2() : {list, integer}
|
||||
RETURNR [1, 2]
|
||||
|
||||
|
||||
FUNCTION no_bits() : bits
|
||||
RETURNR <>
|
||||
|
||||
FUNCTION all_bits() : bits
|
||||
RETURNR !<>
|
||||
|
||||
FUNCTION some_bits() : bits
|
||||
RETURNR <101010>
|
||||
|
||||
FUNCTION many_bits() : bits
|
||||
RETURNR !<010101>
|
||||
|
||||
FUNCTION group_bits() : bits
|
||||
RETURNR <1010 1010 0011 1001>
|
||||
|
||||
FUNCTION unit() : {tuple, []}
|
||||
RETURNR ()
|
||||
|
||||
FUNCTION tuple() : {tuple, [integer, boolean, string, {tuple, [integer, integer]}]}
|
||||
RETURNR (42, true, "FooBar", (1, 2))
|
||||
|
||||
|
||||
|
7
test/asm_code/mapofmap.fate
Normal file
7
test/asm_code/mapofmap.fate
Normal file
@ -0,0 +1,7 @@
|
||||
;; CONTRACT mapofmap
|
||||
FUNCTION map() : {map, integer, {map, string, boolean}}
|
||||
RETURNR {1 => { "foo" => true, "bar" => false},
|
||||
2 => {},
|
||||
3 => { "foo" => false}}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user