79
77
attribute -> '-' atom typed_attr_val : build_typed_attribute('$2','$3').
80
78
attribute -> '-' atom '(' typed_attr_val ')' : build_typed_attribute('$2','$4').
81
79
attribute -> '-' 'spec' type_spec : build_type_spec('$2', '$3').
83
atom1 -> 'spec' : {atom, ?line('$1'), 'spec'}.
86
81
type_spec -> spec_fun type_sigs : {'$1', '$2'}.
87
82
type_spec -> '(' spec_fun type_sigs ')' : {'$2', '$3'}.
89
spec_fun -> atom1 : '$1'.
90
spec_fun -> atom1 ':' atom1 : {'$1', '$3'}.
84
spec_fun -> atom : '$1'.
85
spec_fun -> atom ':' atom : {'$1', '$3'}.
91
86
%% The following two are retained only for backwards compatibility;
92
87
%% they are not part of the EEP syntax and should be removed.
93
spec_fun -> atom1 '/' integer '::' : {'$1', '$3'}.
94
spec_fun -> atom1 ':' atom1 '/' integer '::' : {'$1', '$3', '$5'}.
88
spec_fun -> atom '/' integer '::' : {'$1', '$3'}.
89
spec_fun -> atom ':' atom '/' integer '::' : {'$1', '$3', '$5'}.
96
91
typed_attr_val -> expr ',' typed_record_fields : {typed_record, '$1', '$3'}.
97
92
typed_attr_val -> expr '::' top_type : {type_def, '$1', '$3'}.
124
120
top_type -> var '::' top_type_100 : {ann_type, ?line('$1'), ['$1','$3']}.
125
121
top_type -> top_type_100 : '$1'.
127
top_type_100 -> type : '$1'.
128
top_type_100 -> type '|' top_type_100 : lift_unions('$1','$3').
123
top_type_100 -> type_200 : '$1'.
124
top_type_100 -> type_200 '|' top_type_100 : lift_unions('$1','$3').
126
type_200 -> type_300 '..' type_300 : {type, ?line('$1'), range,
129
type_200 -> type_300 : '$1'.
131
type_300 -> type_300 add_op type_400 : ?mkop2(skip_paren('$1'),
132
'$2', skip_paren('$3')).
133
type_300 -> type_400 : '$1'.
135
type_400 -> type_400 mult_op type_500 : ?mkop2(skip_paren('$1'),
136
'$2', skip_paren('$3')).
137
type_400 -> type_500 : '$1'.
139
type_500 -> prefix_op type : ?mkop1('$1', skip_paren('$2')).
140
type_500 -> type : '$1'.
130
142
type -> '(' top_type ')' : {paren_type, ?line('$2'), ['$2']}.
131
143
type -> var : '$1'.
132
type -> atom1 : '$1'.
133
type -> atom1 '(' ')' : build_gen_type('$1').
134
type -> atom1 '(' top_types ')' : {type, ?line('$1'),
145
type -> atom '(' ')' : build_gen_type('$1').
146
type -> atom '(' top_types ')' : {type, ?line('$1'),
135
147
normalise('$1'), '$3'}.
136
type -> atom1 ':' atom1 '(' ')' : {remote_type, ?line('$1'),
148
type -> atom ':' atom '(' ')' : {remote_type, ?line('$1'),
137
149
['$1', '$3', []]}.
138
type -> atom1 ':' atom1 '(' top_types ')' : {remote_type, ?line('$1'),
150
type -> atom ':' atom '(' top_types ')' : {remote_type, ?line('$1'),
139
151
['$1', '$3', '$5']}.
140
152
type -> '[' ']' : {type, ?line('$1'), nil, []}.
141
153
type -> '[' top_type ']' : {type, ?line('$1'), list, ['$2']}.
142
type -> '[' top_type ',' '.' '.' '.' ']' : {type, ?line('$1'),
154
type -> '[' top_type ',' '...' ']' : {type, ?line('$1'),
143
155
nonempty_list, ['$2']}.
144
156
type -> '{' '}' : {type, ?line('$1'), tuple, []}.
145
157
type -> '{' top_types '}' : {type, ?line('$1'), tuple, '$2'}.
146
type -> '#' atom1 '{' '}' : {type, ?line('$1'), record, ['$2']}.
147
type -> '#' atom1 '{' field_types '}' : {type, ?line('$1'),
158
type -> '#' atom '{' '}' : {type, ?line('$1'), record, ['$2']}.
159
type -> '#' atom '{' field_types '}' : {type, ?line('$1'),
148
160
record, ['$2'|'$4']}.
149
161
type -> binary_type : '$1'.
150
type -> int_type : '$1'.
151
type -> int_type '.' '.' int_type : {type, ?line('$1'), range,
162
type -> integer : '$1'.
153
163
type -> 'fun' '(' ')' : {type, ?line('$1'), 'fun', []}.
154
164
type -> 'fun' '(' fun_type_100 ')' : '$3'.
156
int_type -> integer : '$1'.
157
int_type -> '-' integer : abstract(-normalise('$2'),
160
fun_type_100 -> '(' '.' '.' '.' ')' '->' top_type
166
fun_type_100 -> '(' '...' ')' '->' top_type
161
167
: {type, ?line('$1'), 'fun',
162
[{type, ?line('$1'), any}, '$7']}.
168
[{type, ?line('$1'), any}, '$5']}.
163
169
fun_type_100 -> fun_type : '$1'.
165
171
fun_type -> '(' ')' '->' top_type : {type, ?line('$1'), 'fun',
166
172
[{type, ?line('$1'), product, []}, '$4']}.
167
fun_type -> '(' top_types ')' '->' top_type
173
fun_type -> '(' top_types ')' '->' top_type
168
174
: {type, ?line('$1'), 'fun',
169
175
[{type, ?line('$1'), product, '$2'},'$5']}.
171
177
field_types -> field_type : ['$1'].
172
178
field_types -> field_type ',' field_types : ['$1'|'$3'].
174
field_type -> atom1 '::' top_type : {type, ?line('$1'), field_type,
180
field_type -> atom '::' top_type : {type, ?line('$1'), field_type,
177
binary_type -> '<<' '>>' : {type, ?line('$1'),binary,
178
[abstract(0, ?line('$1')),
183
binary_type -> '<<' '>>' : {type, ?line('$1'),binary,
184
[abstract(0, ?line('$1')),
179
185
abstract(0, ?line('$1'))]}.
180
186
binary_type -> '<<' bin_base_type '>>' : {type, ?line('$1'),binary,
181
187
['$2', abstract(0, ?line('$1'))]}.
333
338
%% N.B. Field names are returned as the complete object, even if they are
334
339
%% always atoms for the moment, this might change in the future.
336
record_expr -> '#' atom1 '.' atom1 :
341
record_expr -> '#' atom '.' atom :
337
342
{record_index,?line('$1'),element(3, '$2'),'$4'}.
338
record_expr -> '#' atom1 record_tuple :
343
record_expr -> '#' atom record_tuple :
339
344
{record,?line('$1'),element(3, '$2'),'$3'}.
340
record_expr -> expr_max '#' atom1 '.' atom1 :
341
{record_field,?line('$2'),'$1',element(3, '$3'),'$5'}.
342
record_expr -> expr_max '#' atom1 record_tuple :
345
record_expr -> expr_max '#' atom '.' atom :
346
{record_field,?line('$2'),'$1',element(3, '$3'),'$5'}.
347
record_expr -> expr_max '#' atom record_tuple :
348
{record,?line('$2'),'$1',element(3, '$3'),'$4'}.
349
record_expr -> record_expr '#' atom '.' atom :
350
{record_field,?line('$2'),'$1',element(3, '$3'),'$5'}.
351
record_expr -> record_expr '#' atom record_tuple :
343
352
{record,?line('$2'),'$1',element(3, '$3'),'$4'}.
345
354
record_tuple -> '{' '}' : [].
415
424
try_clause -> expr clause_guard clause_body :
417
426
{clause,L,[{tuple,L,[{atom,L,throw},'$1',{var,L,'_'}]}],'$2','$3'}.
418
try_clause -> atom1 ':' expr clause_guard clause_body :
427
try_clause -> atom ':' expr clause_guard clause_body :
420
429
{clause,L,[{tuple,L,['$1','$3',{var,L,'_'}]}],'$4','$5'}.
421
430
try_clause -> var ':' expr clause_guard clause_body :
423
432
{clause,L,[{tuple,L,['$1','$3',{var,L,'_'}]}],'$4','$5'}.
425
%%cond_expr -> 'cond' cond_clauses 'end' : {'cond',?line('$1'),'$2'}.
427
%%cond_clauses -> cond_clause : ['$1'].
428
%%cond_clauses -> cond_clause ';' cond_clauses : ['$1' | '$3'].
430
%%cond_clause -> expr clause_body :
431
%% {clause,?line('$1'),[],[['$1']],'$2'}.
433
434
query_expr -> 'query' list_comprehension 'end' :
434
435
{'query',?line('$1'),'$2'}.
605
608
{type, _, 'fun', [{type, _, product, Args},_]} = Fun,
611
build_def(LHS, Types) ->
612
IsSubType = {atom, ?line(LHS), is_subtype},
613
{type, ?line(LHS), constraint, [IsSubType, [LHS, Types]]}.
608
615
lift_unions(T1, {type, _La, union, List}) ->
609
616
{type, ?line(T1), union, [T1|List]};
610
617
lift_unions(T1, T2) ->
611
618
{type, ?line(T1), union, [T1, T2]}.
620
skip_paren({paren_type,_L,[Type]}) ->
613
625
build_gen_type({atom, La, tuple}) ->
614
626
{type, La, tuple, any};
615
627
build_gen_type({atom, La, Name}) ->
739
751
[{record_field,La,{atom,La,A},Expr}|record_fields(Fields)];
740
752
record_fields([{typed,Expr,TypeInfo}|Fields]) ->
741
753
[Field] = record_fields([Expr]),
744
756
{match, _, _, _} -> TypeInfo; %% If we have an initializer.
746
lift_unions(abstract(undefined, La), TypeInfo)
758
case has_undefined(TypeInfo) of
760
lift_unions(abstract(undefined, La), TypeInfo);
748
765
[{typed_record_field,Field,TypeInfo1}|record_fields(Fields)];
749
766
record_fields([Other|_Fields]) ->
750
767
ret_err(?line(Other), "bad record field");
751
768
record_fields([]) -> [].
770
has_undefined({atom,_,undefined}) ->
772
has_undefined({ann_type,_,[_,T]}) ->
774
has_undefined({paren_type,_,[T]}) ->
776
has_undefined({type,_,union,Ts}) ->
777
lists:any(fun has_undefined/1, Ts);
754
782
try normalise(Expr)
755
783
catch _:_R -> ret_err(?line(Expr), "bad attribute")