/
gleam_parser.yrl
133 lines (103 loc) · 4.24 KB
/
gleam_parser.yrl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
Nonterminals
source module functions function
exprs expr adt literal args elems
exports export export_names.
Terminals
'(' ')' '[' ']' '::'
',' '='
'<=' '<' '>' '>='
'/' '*' '+' '-' '/.' '*.' '+.' '-.'
int float atom string
name upname call upcall
kw_module kw_fn kw_export.
Rootsymbol source.
Nonassoc 300 '+'.
Nonassoc 300 '-'.
Nonassoc 300 '+.'.
Nonassoc 300 '-.'.
Right 60 '::'.
Left 220 '*'.
Left 220 '/'.
Left 220 '*.'.
Left 220 '/.'.
Left 160 '<'.
Left 160 '>'.
Left 160 '<='.
Left 160 '>='.
% Left 170 '|>'.
source -> module : '$1'.
source -> exprs : '$1'.
module -> kw_module upname : module('$2', [], []).
module -> kw_module upname functions : module('$2', [], '$3').
module -> kw_module upname exports : module('$2', '$3', []).
module -> kw_module upname exports functions : module('$2', '$3', '$4').
exports -> export : '$1'.
exports -> export exports : '$1' ++ '$2'.
export -> kw_export export_names : '$2'.
export_names -> name '/' int : [export('$1', '$3')].
export_names -> name '/' int ',' export_names : [export('$1', '$3') | '$5'].
functions -> function : ['$1'].
functions -> function functions : ['$1'|'$2'].
function -> kw_fn call ')' '=' exprs : function('$2', [], '$5').
function -> kw_fn call args ')' '=' exprs : function('$2', '$3', '$6').
exprs -> name '=' expr exprs : [assignment('$1', '$3', '$4')].
exprs -> expr : ['$1'].
exprs -> expr exprs : ['$1'|'$2'].
expr -> literal : '$1'.
expr -> adt : '$1'.
expr -> name : var('$1').
expr -> call elems ')' : local_call('$1', '$2').
expr -> expr '::' expr : local_call('::', ['$1', '$3']).
expr -> expr '+' expr : local_call('+', ['$1', '$3']).
expr -> expr '-' expr : local_call('-', ['$1', '$3']).
expr -> expr '*' expr : local_call('*', ['$1', '$3']).
expr -> expr '/' expr : local_call('/', ['$1', '$3']).
expr -> expr '+.' expr : local_call('+.', ['$1', '$3']).
expr -> expr '-.' expr : local_call('-.', ['$1', '$3']).
expr -> expr '*.' expr : local_call('*.', ['$1', '$3']).
expr -> expr '/.' expr : local_call('/.', ['$1', '$3']).
expr -> expr '<=' expr : local_call('<=', ['$1', '$3']).
expr -> expr '<' expr : local_call('<' , ['$1', '$3']).
expr -> expr '>' expr : local_call('>' , ['$1', '$3']).
expr -> expr '>=' expr : local_call('>=', ['$1', '$3']).
args -> name : [arg('$1')].
args -> name ',' : [arg('$1')].
args -> name ',' args : [arg('$1') | '$3'].
elems -> expr : ['$1'].
elems -> expr ',' : ['$1'].
elems -> expr ',' elems : ['$1' | '$3'].
adt -> upname : adt('$1', []).
adt -> upcall elems ')' : adt('$1', '$2').
literal -> '(' ')' : tuple([]).
literal -> '(' elems ')' : tuple('$2').
literal -> '[' ']' : list([]).
literal -> '[' elems ']' : list('$2').
literal -> atom : literal('$1').
literal -> int : literal('$1').
literal -> float : literal('$1').
literal -> string : literal('$1').
Erlang code.
-include("gleam_records.hrl").
module({upname, _, Name}, Exports, Functions) ->
#ast_module{name = Name, exports = Exports, functions = Functions}.
local_call({call, _, Name}, Args) ->
#ast_local_call{name = Name, args = Args};
local_call(Name, Args) when is_atom(Name) ->
#ast_local_call{name = Name, args = Args}.
% call(Mod, Name, Args) ->
% #ast_call{module = Mod, name = Name, args = Args}.
function({call, Meta, Name}, Args, Body) ->
#ast_function{meta = Meta, name = Name, args = Args, body = Body}.
assignment({name, _, Name}, Value, Then) ->
#ast_assignment{name = Name, value = Value, then = Then}.
arg({name, _Meta, Name}) -> Name.
var({name, Meta, Name}) -> #ast_var{meta = Meta, name = Name}.
export({name, _, Name}, {int, _, Arity}) -> {Name, Arity}.
tuple(Elems) -> #ast_tuple{elems = Elems}.
list(Elems) -> #ast_list{elems = Elems}.
adt({Type, Meta, Name}, Elems) when Type =:= upname; Type =:= upcall ->
#ast_adt{name = Name, meta = Meta, elems = Elems}.
literal({atom, Meta, Value}) -> #ast_atom{meta = Meta, value = Value};
literal({int, Meta, Value}) -> #ast_int{meta = Meta, value = Value};
literal({float, Meta, Value}) -> #ast_float{meta = Meta, value = Value};
literal({string, Meta, Value}) -> #ast_string{meta = Meta, value = Value}.