@@ -2,12 +2,11 @@ defmodule Xpeg.Codegen do
2
2
@ moduledoc false
3
3
4
4
defp emit_inst ( ip , inst , options ) do
5
-
6
5
case inst do
7
6
{ :nop } ->
8
7
quote location: :keep do
9
8
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures ) do
10
- parse ( unquote ( ip + 1 ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
9
+ parse ( unquote ( ip + 1 ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
11
10
end
12
11
end
13
12
@@ -16,42 +15,100 @@ defmodule Xpeg.Codegen do
16
15
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures ) do
17
16
parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures , unquote ( n ) )
18
17
end
18
+
19
19
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures , n ) do
20
20
case { s , n } do
21
- { [ _ | s2 ] , 1 } -> parse ( unquote ( ip + 1 ) , s2 , si + 1 , ctx , back_stack , ret_stack , cap_stack , captures )
22
- { [ _ | s2 ] , m } -> parse ( unquote ( ip ) , s2 , si + 1 , ctx , back_stack , ret_stack , cap_stack , captures , m - 1 )
23
- { [ ] , _ } -> parse ( :fail , [ ] , si , ctx , back_stack , ret_stack , cap_stack , captures )
21
+ { [ _ | s2 ] , 1 } ->
22
+ parse (
23
+ unquote ( ip + 1 ) ,
24
+ s2 ,
25
+ si + 1 ,
26
+ ctx ,
27
+ back_stack ,
28
+ ret_stack ,
29
+ cap_stack ,
30
+ captures
31
+ )
32
+
33
+ { [ _ | s2 ] , m } ->
34
+ parse (
35
+ unquote ( ip ) ,
36
+ s2 ,
37
+ si + 1 ,
38
+ ctx ,
39
+ back_stack ,
40
+ ret_stack ,
41
+ cap_stack ,
42
+ captures ,
43
+ m - 1
44
+ )
45
+
46
+ { [ ] , _ } ->
47
+ parse ( :fail , [ ] , si , ctx , back_stack , ret_stack , cap_stack , captures )
24
48
end
25
49
end
26
50
end
27
51
28
52
{ :chr , cmatch } ->
29
53
quote location: :keep do
30
- def parse ( unquote ( ip ) , s = [ c | s2 ] , si , ctx , back_stack , ret_stack , cap_stack , captures ) when c == unquote ( cmatch ) do
31
- parse ( unquote ( ip + 1 ) , s2 , si + 1 , ctx , back_stack , ret_stack , cap_stack , captures )
54
+ def parse (
55
+ unquote ( ip ) ,
56
+ s = [ c | s2 ] ,
57
+ si ,
58
+ ctx ,
59
+ back_stack ,
60
+ ret_stack ,
61
+ cap_stack ,
62
+ captures
63
+ )
64
+ when c == unquote ( cmatch ) do
65
+ parse ( unquote ( ip + 1 ) , s2 , si + 1 , ctx , back_stack , ret_stack , cap_stack , captures )
32
66
end
67
+
33
68
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures ) do
34
69
parse ( :fail , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
35
70
end
36
71
end
37
72
38
73
{ :set , cs } ->
39
74
quote location: :keep do
40
- def parse ( unquote ( ip ) , s = [ c | s2 ] , si , ctx , back_stack , ret_stack , cap_stack , captures ) when c in unquote ( cs ) do
41
- parse ( unquote ( ip + 1 ) , s2 , si + 1 , ctx , back_stack , ret_stack , cap_stack , captures )
75
+ def parse (
76
+ unquote ( ip ) ,
77
+ s = [ c | s2 ] ,
78
+ si ,
79
+ ctx ,
80
+ back_stack ,
81
+ ret_stack ,
82
+ cap_stack ,
83
+ captures
84
+ )
85
+ when c in unquote ( cs ) do
86
+ parse ( unquote ( ip + 1 ) , s2 , si + 1 , ctx , back_stack , ret_stack , cap_stack , captures )
42
87
end
88
+
43
89
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures ) do
44
90
parse ( :fail , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
45
91
end
46
92
end
47
93
48
94
{ :span , cs } ->
49
95
quote location: :keep do
50
- def parse ( unquote ( ip ) , s = [ c | s2 ] , si , ctx , back_stack , ret_stack , cap_stack , captures ) when c in unquote ( cs ) do
51
- parse ( unquote ( ip ) , s2 , si + 1 , ctx , back_stack , ret_stack , cap_stack , captures )
96
+ def parse (
97
+ unquote ( ip ) ,
98
+ s = [ c | s2 ] ,
99
+ si ,
100
+ ctx ,
101
+ back_stack ,
102
+ ret_stack ,
103
+ cap_stack ,
104
+ captures
105
+ )
106
+ when c in unquote ( cs ) do
107
+ parse ( unquote ( ip ) , s2 , si + 1 , ctx , back_stack , ret_stack , cap_stack , captures )
52
108
end
109
+
53
110
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures ) do
54
- parse ( unquote ( ip + 1 ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
111
+ parse ( unquote ( ip + 1 ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
55
112
end
56
113
end
57
114
@@ -61,6 +118,7 @@ defmodule Xpeg.Codegen do
61
118
case ret_stack do
62
119
[ ip | ret_stack ] ->
63
120
parse ( ip , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
121
+
64
122
[ ] ->
65
123
{ ctx , s , si , :ok , cap_stack , captures }
66
124
end
@@ -70,25 +128,25 @@ defmodule Xpeg.Codegen do
70
128
{ :choice , ip_back , ip_commit } ->
71
129
quote location: :keep do
72
130
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures ) do
73
- frame = { unquote ( ip_back ) , unquote ( ip_commit ) , ret_stack , cap_stack , s , si }
131
+ frame = { unquote ( ip_back ) , unquote ( ip_commit ) , ret_stack , cap_stack , s , si }
74
132
back_stack = [ frame | back_stack ]
75
- parse ( unquote ( ip + 1 ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
133
+ parse ( unquote ( ip + 1 ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
76
134
end
77
135
end
78
136
79
137
{ :commit } ->
80
138
quote location: :keep do
81
139
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures ) do
82
140
[ frame | back_stack ] = back_stack
83
- { _ , ip , _ , _ , _ , _ } = frame
141
+ { _ , ip , _ , _ , _ , _ } = frame
84
142
parse ( ip , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
85
143
end
86
144
end
87
145
88
146
{ :call , addr } ->
89
147
quote location: :keep do
90
148
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures ) do
91
- ret_stack = [ unquote ( ip + 1 ) | ret_stack ]
149
+ ret_stack = [ unquote ( ip + 1 ) | ret_stack ]
92
150
parse ( unquote ( addr ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
93
151
end
94
152
end
@@ -104,15 +162,15 @@ defmodule Xpeg.Codegen do
104
162
quote location: :keep do
105
163
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures ) do
106
164
cap_stack = [ { :open , s , si } | cap_stack ]
107
- parse ( unquote ( ip + 1 ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
165
+ parse ( unquote ( ip + 1 ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
108
166
end
109
167
end
110
168
111
169
{ :capclose , type } ->
112
- quote location: :keep do
170
+ quote location: :keep do
113
171
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures ) do
114
172
cap_stack = [ { :close , s , si , unquote ( type ) } | cap_stack ]
115
- parse ( unquote ( ip + 1 ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
173
+ parse ( unquote ( ip + 1 ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
116
174
end
117
175
end
118
176
@@ -121,11 +179,14 @@ defmodule Xpeg.Codegen do
121
179
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures ) do
122
180
{ cap_stack , captures } = Xpeg . collect_captures ( cap_stack , captures )
123
181
func = unquote ( code )
124
- { captures , ctx } = case unquote ( options [ :userdata ] ) do
125
- true -> func . ( captures , ctx )
126
- _ -> { func . ( captures ) , ctx }
127
- end
128
- parse ( unquote ( ip + 1 ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
182
+
183
+ { captures , ctx } =
184
+ case unquote ( options [ :userdata ] ) do
185
+ true -> func . ( captures , ctx )
186
+ _ -> { func . ( captures ) , ctx }
187
+ end
188
+
189
+ parse ( unquote ( ip + 1 ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
129
190
end
130
191
end
131
192
@@ -134,8 +195,9 @@ defmodule Xpeg.Codegen do
134
195
def parse ( unquote ( ip ) , s , si , ctx , back_stack , ret_stack , cap_stack , captures ) do
135
196
case back_stack do
136
197
[ frame | back_stack ] ->
137
- { ip , _ , ret_stack , cap_stack , s , si } = frame
198
+ { ip , _ , ret_stack , cap_stack , s , si } = frame
138
199
parse ( ip , s , si , ctx , back_stack , ret_stack , cap_stack , captures )
200
+
139
201
[ ] ->
140
202
{ ctx , s , si , :error , cap_stack , captures }
141
203
end
@@ -144,50 +206,59 @@ defmodule Xpeg.Codegen do
144
206
end
145
207
end
146
208
147
-
148
209
def add_trace ( options , ast , ip , inst ) do
149
210
if options [ :trace ] do
150
- { ast , _ } = Macro . prewalk ( ast , false , fn
151
- { :do , body } , false ->
152
- body = quote do
153
- Xpeg . trace ( unquote ( ip ) , unquote ( inspect ( inst ) ) , s )
154
- unquote ( body )
155
- end
156
- { { :do , body } , true }
157
- e , done -> { e , done }
158
- end )
211
+ { ast , _ } =
212
+ Macro . prewalk ( ast , false , fn
213
+ { :do , body } , false ->
214
+ body =
215
+ quote do
216
+ Xpeg . trace ( unquote ( ip ) , unquote ( inspect ( inst ) ) , s )
217
+ unquote ( body )
218
+ end
219
+
220
+ { { :do , body } , true }
221
+
222
+ e , done ->
223
+ { e , done }
224
+ end )
225
+
159
226
ast
160
227
else
161
228
ast
162
229
end
163
230
end
164
231
165
-
166
232
def emit ( program , options \\ [ ] ) do
233
+ ast =
234
+ Enum . reduce ( program . instructions , [ ] , fn { ip , inst } , defs ->
235
+ ast = emit_inst ( ip , inst , options )
167
236
168
- ast = Enum . reduce ( program . instructions , [ ] , fn { ip , inst } , defs ->
169
- ast = emit_inst ( ip , inst , options )
170
- case ast do
171
- { :__block__ , _ , subs } ->
172
- Enum . map ( subs , & add_trace ( options , & 1 , ip , inst ) ) ++ defs
173
- _ -> [ add_trace ( options , ast , ip , inst ) | defs ]
174
- end
175
- end )
237
+ case ast do
238
+ { :__block__ , _ , subs } ->
239
+ Enum . map ( subs , & add_trace ( options , & 1 , ip , inst ) ) ++ defs
240
+
241
+ _ ->
242
+ [ add_trace ( options , ast , ip , inst ) | defs ]
243
+ end
244
+ end )
176
245
177
246
ast = {
178
- :__block__ , [ ] , [ quote do
179
- require Xpeg
180
- end ] ++ ast
247
+ :__block__ ,
248
+ [ ] ,
249
+ [
250
+ quote do
251
+ require Xpeg
252
+ end
253
+ ] ++ ast
181
254
}
182
255
183
256
if options [ :dump_code ] do
184
257
IO . puts ( Macro . to_string ( ast ) )
185
258
end
186
259
187
260
Macro . escape ( ast )
188
-
189
261
end
190
-
191
262
end
192
263
193
264
# set ft=elixir
0 commit comments