|
| 1 | +Terminals '(' ')' '[' ']' ',' '->' int atom binary 'expecting selector' 'expecting type'. |
| 2 | +Nonterminals dispatch selector nontrivial_selector comma_delimited_types type_with_subscripts array_subscripts tuple array_subscript identifier type typespec. |
| 3 | +Rootsymbol dispatch. |
| 4 | + |
| 5 | +dispatch -> 'expecting type' type_with_subscripts : {type, '$2'}. |
| 6 | +dispatch -> 'expecting selector' selector : {selector, '$2'}. |
| 7 | +dispatch -> type_with_subscripts : {selector, #{function => nil, types => ['$1'], returns => nil}}. |
| 8 | +dispatch -> nontrivial_selector : {selector, '$1'}. |
| 9 | + |
| 10 | +selector -> typespec : #{function => nil, types => '$1', returns => nil}. |
| 11 | +selector -> nontrivial_selector : '$1'. |
| 12 | + |
| 13 | +nontrivial_selector -> typespec '->' type : #{function => nil, types => '$1', returns => '$3'}. |
| 14 | +nontrivial_selector -> identifier typespec : #{function => '$1', types => '$2', returns => nil}. |
| 15 | +nontrivial_selector -> identifier typespec '->' type : #{function => '$1', types => '$2', returns => '$4'}. |
| 16 | + |
| 17 | +typespec -> '(' ')' : []. |
| 18 | +typespec -> '(' comma_delimited_types ')' : '$2'. |
| 19 | + |
| 20 | +tuple -> '(' ')' : {tuple, []}. |
| 21 | +tuple -> '(' comma_delimited_types ')' : {tuple, '$2'}. |
| 22 | + |
| 23 | +comma_delimited_types -> type_with_subscripts : ['$1']. |
| 24 | +comma_delimited_types -> type_with_subscripts ',' comma_delimited_types : ['$1' | '$3']. |
| 25 | + |
| 26 | +identifier -> atom : atom_to_list(v('$1')). |
| 27 | +identifier -> binary : v('$1'). |
| 28 | + |
| 29 | +type_with_subscripts -> type : '$1'. |
| 30 | +type_with_subscripts -> type array_subscripts : with_subscripts('$1', '$2'). |
| 31 | + |
| 32 | +array_subscripts -> array_subscript : ['$1']. |
| 33 | +array_subscripts -> array_subscript array_subscripts : ['$1' | '$2']. |
| 34 | + |
| 35 | +array_subscript -> '[' ']' : variable. |
| 36 | +array_subscript -> '[' int ']' : v('$2'). |
| 37 | + |
| 38 | +type -> atom : |
| 39 | + plain_type(v('$1')). |
| 40 | +type -> atom int : |
| 41 | + juxt_type(v('$1'), v('$2')). |
| 42 | +type -> atom int identifier int : |
| 43 | + double_juxt_type(v('$1'), v('$4'), v('$2'), v('$3')). |
| 44 | +type -> tuple : '$1'. |
| 45 | + |
| 46 | + |
| 47 | +Erlang code. |
| 48 | + |
| 49 | +v({_Token, _Line, Value}) -> Value. |
| 50 | + |
| 51 | +plain_type(address) -> address; |
| 52 | +plain_type(bool) -> bool; |
| 53 | +plain_type(function) -> function; |
| 54 | +plain_type(string) -> string; |
| 55 | +plain_type(bytes) -> bytes; |
| 56 | +plain_type(int) -> juxt_type(int, 256); |
| 57 | +plain_type(uint) -> juxt_type(uint, 256); |
| 58 | +plain_type(fixed) -> double_juxt_type(fixed, "x", 128, 19); |
| 59 | +plain_type(ufixed) -> double_juxt_type(ufixed, "x", 128, 19). |
| 60 | + |
| 61 | +with_subscripts(Type, []) -> Type; |
| 62 | +with_subscripts(Type, [H | T]) -> with_subscripts(with_subscript(Type, H), T). |
| 63 | + |
| 64 | +with_subscript(Type, variable) -> {array, Type}; |
| 65 | +with_subscript(Type, N) when is_integer(N), N >= 0 -> {array, Type, N}. |
| 66 | + |
| 67 | +juxt_type(int, M) when M > 0, M =< 256, (M rem 8) =:= 0 -> {int, M}; |
| 68 | +juxt_type(uint, M) when M > 0, M =< 256, (M rem 8) =:= 0 -> {uint, M}; |
| 69 | +juxt_type(bytes, M) when M > 0, M =< 32 -> {bytes, M}. |
| 70 | + |
| 71 | +double_juxt_type(fixed, "x", M, N) when M >= 0, M =< 256, (M rem 8) =:= 0, N > 0, N =< 80 -> {fixed, M, N}; |
| 72 | +double_juxt_type(ufixed, "x", M, N) when M >= 0, M =< 256, (M rem 8) =:= 0, N > 0, N =< 80 -> {ufixed, M, N}. |
0 commit comments