metal 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Manifest.txt +14 -1
- data/bin/metal +63 -16
- data/bin/metal-run +16 -13
- data/config/hoe.rb +4 -2
- data/ext/metal/boot/metal_boot.h +32 -0
- data/{lib/metal/boot.metal → ext/metal/boot/metal_boot.metal} +40 -53
- data/ext/metal/boot/metal_boot.mm +1294 -0
- data/ext/metal/boot/metal_boot_extconf.rb +16 -0
- data/ext/metal/boot/metal_boot_rb.mm +20 -0
- data/ext/metal/runtime/extconf.rb +35 -0
- data/ext/metal/runtime/input.mm +99 -0
- data/ext/metal/runtime/rbinit.mm +17 -0
- data/ext/metal/runtime/runtime.mm +660 -0
- data/include/metal.h +4 -0
- data/include/metal/exception.h +15 -0
- data/include/metal/input.h +42 -0
- data/include/metal/rbcode.h +24 -0
- data/include/metal/runtime.h +97 -0
- data/lib/metal/boot.rb +1 -353
- data/lib/metal/generator.rb +313 -203
- data/lib/metal/runtime.rb +1 -386
- data/lib/metal/version.rb +1 -1
- metadata +32 -8
data/lib/metal/generator.rb
CHANGED
|
@@ -19,296 +19,406 @@
|
|
|
19
19
|
module Metal
|
|
20
20
|
module Generator
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
attr_reader :out
|
|
29
|
-
attr_accessor :rule
|
|
30
|
-
attr_accessor :grammar
|
|
22
|
+
def self.escape_quoated_string(str)
|
|
23
|
+
str = str.gsub("\\", "\\\\\\\\")
|
|
24
|
+
str.gsub!("\"", "\\\\\"")
|
|
25
|
+
str_len = string_length(str)
|
|
26
|
+
str.gsub!("\n", "\\\\n\"\n\"")
|
|
27
|
+
return str, str_len
|
|
31
28
|
end
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
__send__("gen_#{lang}", ctx)
|
|
37
|
-
ctx.out
|
|
38
|
-
end
|
|
29
|
+
|
|
30
|
+
def self.string_length(str)
|
|
31
|
+
#@str.bytesize # FIXME Ruby 1.9
|
|
32
|
+
str.size - str.scan(/\\/).length + str.scan(/\\\\/).length;
|
|
39
33
|
end
|
|
40
|
-
|
|
41
|
-
class Meta
|
|
42
|
-
def initialize(
|
|
43
|
-
@grammars =
|
|
34
|
+
|
|
35
|
+
class Meta
|
|
36
|
+
def initialize(codes)
|
|
37
|
+
@grammars, @precodes = codes.partition {|i| i.is_a?(Grammar) }
|
|
38
|
+
@vars = []
|
|
39
|
+
@grammar = nil
|
|
40
|
+
@rule = nil
|
|
44
41
|
end
|
|
45
|
-
def
|
|
46
|
-
@grammars.each {|
|
|
47
|
-
|
|
42
|
+
def generate(fname, source = '', header = '', rbcode = '')
|
|
43
|
+
@grammars.each {|grammar|
|
|
44
|
+
grammar.preprocess(self)
|
|
48
45
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
|
|
47
|
+
header << "#import \"metal/runtime.h\"\n"
|
|
48
|
+
source << "#import \"#{fname}.h\"\n"
|
|
49
|
+
source << "using namespace Metal;\n"
|
|
50
|
+
|
|
51
|
+
@vars.sort!
|
|
52
|
+
@vars.uniq!
|
|
53
|
+
@vars.each {|var|
|
|
54
|
+
source << "static param_t const PARAM_#{var} = param_lookup(\"#{var}\");\n"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
rbcode << <<END
|
|
58
|
+
#import "ruby.h"
|
|
59
|
+
#import "metal/rbcode.h"
|
|
60
|
+
#import "#{fname}.h"
|
|
61
|
+
#ifdef __cplusplus
|
|
62
|
+
extern "C" {
|
|
63
|
+
#endif
|
|
64
|
+
void Init_#{fname}() {
|
|
65
|
+
VALUE mMetal = rb_define_module("Metal");
|
|
66
|
+
VALUE cBase = rb_define_class_under(mMetal, "ParserBase", rb_cObject);
|
|
67
|
+
VALUE code;
|
|
68
|
+
END
|
|
69
|
+
|
|
70
|
+
@precodes.each {|precode|
|
|
71
|
+
code, code_len = Generator.escape_quoated_string(precode.code)
|
|
72
|
+
rbcode << "rb_eval_string(\"#{code}\");\n"
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@grammars.each {|grammar|
|
|
76
|
+
grammar.generate(self, source, header, rbcode)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
rbcode << <<END
|
|
80
|
+
}
|
|
81
|
+
#ifdef __cplusplus
|
|
82
|
+
}
|
|
83
|
+
#endif
|
|
84
|
+
END
|
|
85
|
+
|
|
86
|
+
return [source, header, rbcode]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
attr_accessor :meta, :grammar, :rule
|
|
90
|
+
|
|
91
|
+
def register_var(name)
|
|
92
|
+
@vars.push name
|
|
54
93
|
end
|
|
55
94
|
end
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
@
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class Grammar
|
|
98
|
+
def initialize(name, body, base = nil, category = nil)
|
|
99
|
+
@name = name
|
|
100
|
+
@rules = []; @tokens = [], @precodes = []
|
|
101
|
+
body.each {|b|
|
|
102
|
+
if b.is_a?(Rule)
|
|
103
|
+
@rules.push(b)
|
|
104
|
+
elsif b.is_a?(Token)
|
|
105
|
+
@tokens.push(b)
|
|
106
|
+
else
|
|
107
|
+
@precodes.push(b)
|
|
108
|
+
end
|
|
109
|
+
}
|
|
61
110
|
@base = base
|
|
62
|
-
@
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
111
|
+
@category = category
|
|
112
|
+
end
|
|
113
|
+
def preprocess(ctx)
|
|
114
|
+
ctx.grammar = self
|
|
115
|
+
@rules.each {|rules| rules.preprocess(ctx) }
|
|
116
|
+
# FIXME @tokens
|
|
117
|
+
end
|
|
118
|
+
def generate(ctx, source, header, rbcode)
|
|
119
|
+
ctx.grammar = self
|
|
120
|
+
|
|
121
|
+
if @category
|
|
122
|
+
header << "@interface #{@name} (#{@category})\n"
|
|
123
|
+
else
|
|
124
|
+
header << "@interface #{@name} : #{@base || 'MetalParserBase'}\n"
|
|
125
|
+
end
|
|
126
|
+
@rules.each {|rule|
|
|
127
|
+
header << "-(VALUE)rule_#{rule.name}:(Metal::Context*)ctx;\n"
|
|
128
|
+
}
|
|
129
|
+
# FIXME token
|
|
130
|
+
header << "@end\n"
|
|
131
|
+
|
|
132
|
+
if @category
|
|
133
|
+
source << "@implementation #{@name} (#{@category})\n"
|
|
69
134
|
else
|
|
70
|
-
|
|
135
|
+
source << "@implementation #{@name}\n"
|
|
71
136
|
end
|
|
72
|
-
@rules.each {|
|
|
73
|
-
|
|
137
|
+
@rules.each {|rule|
|
|
138
|
+
source << "-(VALUE)rule_#{rule.name}:(Context*)ctx {\n"
|
|
139
|
+
source << "return ({\n"
|
|
140
|
+
rule.generate(ctx, source)
|
|
141
|
+
source << "});\n"
|
|
142
|
+
source << "}\n"
|
|
74
143
|
}
|
|
75
|
-
|
|
144
|
+
# FIXME token
|
|
145
|
+
source << "@end\n"
|
|
146
|
+
|
|
147
|
+
rbcode << "{\n"
|
|
148
|
+
if @category
|
|
149
|
+
rbcode << "VALUE c#{@name} = rb_const_get(rb_cKernel,rb_intern(\"#{@name}\"));\n"
|
|
150
|
+
else
|
|
151
|
+
rbcode << "VALUE c#{@name} = rb_define_class(\"#{@name}\", #{@base ? "rb_const_get(rb_cKernel,rb_intern(\"#{@base}\"))" : "cBase"});\n";
|
|
152
|
+
rbcode << "rb_define_method(cMetalParser, \"parse\", (VALUE (*)(ANYARGS))(VALUE (*)(VALUE,VALUE))&Metal::parse_method_template<#{@name}>, 1);\n"
|
|
153
|
+
end
|
|
154
|
+
@precodes.each {|precode|
|
|
155
|
+
code, code_len = Generator.escape_quoated_string(precode.code)
|
|
156
|
+
rbcode << "code = rb_str_new(\"#{code}\",#{code_len});\n";
|
|
157
|
+
rbcode << "rb_mod_module_eval(1,&code,c#{@name});\n"
|
|
158
|
+
}
|
|
159
|
+
rbcode << "}\n"
|
|
76
160
|
end
|
|
77
|
-
|
|
78
|
-
def
|
|
79
|
-
|
|
80
|
-
@rules.find {|r| r.is_a?(Rule) && r.name == name }
|
|
161
|
+
attr_reader :name
|
|
162
|
+
def category?
|
|
163
|
+
@category != nil
|
|
81
164
|
end
|
|
82
165
|
end
|
|
83
|
-
|
|
84
|
-
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class Precode
|
|
85
169
|
def initialize(code)
|
|
86
170
|
@code = code
|
|
87
171
|
end
|
|
88
|
-
|
|
89
|
-
ctx.out << @code << "\n"
|
|
90
|
-
end
|
|
172
|
+
attr_reader :code
|
|
91
173
|
end
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class Token
|
|
177
|
+
# FIXME
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
class Rule
|
|
181
|
+
def initialize(name, or_set)
|
|
95
182
|
@name = name
|
|
183
|
+
@or_set = or_set
|
|
184
|
+
|
|
185
|
+
@serial = 0
|
|
96
186
|
end
|
|
97
|
-
def
|
|
98
|
-
ctx.
|
|
187
|
+
def preprocess(ctx)
|
|
188
|
+
ctx.rule = self
|
|
189
|
+
@or_set.preprocess(ctx)
|
|
99
190
|
end
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
@name = name.to_sym
|
|
105
|
-
@or_set = or_set
|
|
106
|
-
@args = args
|
|
191
|
+
def generate(ctx, source)
|
|
192
|
+
ctx.rule = self
|
|
193
|
+
source << "Env env;\n"
|
|
194
|
+
@or_set.generate(ctx, source)
|
|
107
195
|
end
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
@
|
|
112
|
-
|
|
196
|
+
attr_reader :name
|
|
197
|
+
|
|
198
|
+
def with_lambda(source, &block)
|
|
199
|
+
obj = "rule_#{@name}_#{@serial+=1}"
|
|
200
|
+
source << "struct #{obj}_t : Lambda {\n"
|
|
201
|
+
source << "#{obj}_t(Context* _ctx, Env& _env) : Lambda(_ctx, _env) {}\n"
|
|
202
|
+
source << "VALUE call() {\n"
|
|
203
|
+
source << "return ({\n"
|
|
204
|
+
yield
|
|
205
|
+
source << "});\n"
|
|
206
|
+
source << "}\n"
|
|
207
|
+
source << "} #{obj}(ctx, env);\n"
|
|
208
|
+
obj
|
|
113
209
|
end
|
|
114
210
|
end
|
|
115
|
-
|
|
211
|
+
|
|
212
|
+
|
|
116
213
|
class OrSet
|
|
117
|
-
def initialize(
|
|
118
|
-
@
|
|
119
|
-
end
|
|
120
|
-
def
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
@
|
|
127
|
-
ctx
|
|
128
|
-
|
|
129
|
-
|
|
214
|
+
def initialize(and_sets)
|
|
215
|
+
@and_sets = and_sets
|
|
216
|
+
end
|
|
217
|
+
def preprocess(ctx)
|
|
218
|
+
@and_sets.each {|and_set| and_set.preprocess(ctx) }
|
|
219
|
+
end
|
|
220
|
+
def generate(ctx, source)
|
|
221
|
+
if @and_sets.length <= 1
|
|
222
|
+
# optimize
|
|
223
|
+
@and_sets.each {|and_set|
|
|
224
|
+
and_set.generate(ctx, source)
|
|
225
|
+
}
|
|
226
|
+
else
|
|
227
|
+
objs = []
|
|
228
|
+
@and_sets.each {|and_set|
|
|
229
|
+
obj = ctx.rule.with_lambda(source) {
|
|
230
|
+
and_set.generate(ctx, source)
|
|
231
|
+
}
|
|
232
|
+
objs.push obj
|
|
130
233
|
}
|
|
131
|
-
|
|
234
|
+
set_name = "#{objs.first}_or"
|
|
235
|
+
source << "Lambda* #{set_name}[] = {\n"
|
|
236
|
+
objs.each {|obj|
|
|
237
|
+
source << "&#{obj},\n"
|
|
238
|
+
}
|
|
239
|
+
source << "NULL\n"
|
|
240
|
+
source << "};\n"
|
|
241
|
+
source << "ctx->act_or(#{set_name});\n"
|
|
132
242
|
end
|
|
133
243
|
end
|
|
134
244
|
end
|
|
135
|
-
|
|
245
|
+
|
|
136
246
|
class AndSet
|
|
137
247
|
def initialize(exprs)
|
|
138
248
|
@exprs = exprs
|
|
139
249
|
end
|
|
140
|
-
def
|
|
141
|
-
@exprs.each {|
|
|
142
|
-
|
|
143
|
-
|
|
250
|
+
def preprocess(ctx)
|
|
251
|
+
@exprs.each {|expr| expr.preprocess(ctx) }
|
|
252
|
+
end
|
|
253
|
+
def generate(ctx, source)
|
|
254
|
+
@exprs.each {|expr|
|
|
255
|
+
expr.generate(ctx, source)
|
|
144
256
|
}
|
|
145
257
|
end
|
|
146
258
|
end
|
|
147
|
-
|
|
259
|
+
|
|
260
|
+
|
|
148
261
|
class Expression
|
|
149
|
-
def initialize(pred, var)
|
|
262
|
+
def initialize(pred, iter, var)
|
|
150
263
|
@pred = pred
|
|
264
|
+
@iter = iter
|
|
151
265
|
@var = var
|
|
152
266
|
end
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
ctx
|
|
156
|
-
@pred.gen_ruby(ctx)
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
class IterMany
|
|
161
|
-
def initialize(pred)
|
|
162
|
-
@pred = pred
|
|
163
|
-
end
|
|
164
|
-
def gen_ruby(ctx)
|
|
165
|
-
ctx.out << "act_many(lambda{"
|
|
166
|
-
@pred.gen_ruby(ctx)
|
|
167
|
-
ctx.out << "})"
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
class IterMany1
|
|
172
|
-
def initialize(pred)
|
|
173
|
-
@pred = pred
|
|
267
|
+
def preprocess(ctx)
|
|
268
|
+
ctx.register_var(@var) if @var
|
|
269
|
+
@pred.preprocess(ctx)
|
|
174
270
|
end
|
|
175
|
-
def
|
|
176
|
-
|
|
177
|
-
@
|
|
178
|
-
|
|
271
|
+
def generate(ctx, source)
|
|
272
|
+
source << "env[PARAM_#{@var}] = ({\n" if @var
|
|
273
|
+
if @iter
|
|
274
|
+
obj = ctx.rule.with_lambda(source) {
|
|
275
|
+
@pred.generate(ctx, source)
|
|
276
|
+
}
|
|
277
|
+
source << "ctx->act_#{@iter}(&#{obj});\n"
|
|
278
|
+
else
|
|
279
|
+
@pred.generate(ctx, source)
|
|
280
|
+
end
|
|
281
|
+
source << "});\n" if @var
|
|
179
282
|
end
|
|
180
283
|
end
|
|
181
|
-
|
|
182
|
-
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class PredNot
|
|
183
287
|
def initialize(pred)
|
|
184
288
|
@pred = pred
|
|
185
289
|
end
|
|
186
|
-
def
|
|
187
|
-
|
|
188
|
-
@pred.gen_ruby(ctx)
|
|
189
|
-
ctx.out << "})"
|
|
190
|
-
end
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
class Action
|
|
194
|
-
def initialize(action)
|
|
195
|
-
@action = action
|
|
290
|
+
def preprocess(ctx)
|
|
291
|
+
@pred.preprocess(ctx)
|
|
196
292
|
end
|
|
197
|
-
def
|
|
198
|
-
ctx.
|
|
293
|
+
def generate(ctx, source)
|
|
294
|
+
obj = ctx.rule.with_lambda(source) {
|
|
295
|
+
@pred.generate(ctx, source)
|
|
296
|
+
}
|
|
297
|
+
source << "ctx->act_not(&#{obj});\n"
|
|
199
298
|
end
|
|
200
299
|
end
|
|
201
|
-
|
|
202
|
-
class
|
|
203
|
-
def initialize(
|
|
204
|
-
@
|
|
205
|
-
end
|
|
206
|
-
def gen_ruby(ctx)
|
|
207
|
-
ctx.out << "act_where(lambda{#{@action.to_s}})"
|
|
300
|
+
|
|
301
|
+
class PredLookahead
|
|
302
|
+
def initialize(literal)
|
|
303
|
+
@literal = literal
|
|
208
304
|
end
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
class Apply
|
|
212
|
-
def initialize(name, vars)
|
|
213
|
-
@name = name
|
|
214
|
-
@vars = vars
|
|
305
|
+
def preprocess(ctx)
|
|
306
|
+
@literal.preprocess(ctx)
|
|
215
307
|
end
|
|
216
|
-
def
|
|
217
|
-
ctx.
|
|
308
|
+
def generate(ctx, source)
|
|
309
|
+
obj = ctx.rule.with_lambda(source) {
|
|
310
|
+
@literal.generate(ctx, source)
|
|
311
|
+
}
|
|
312
|
+
source << "ctx->act_lookahead(&#{obj});\n"
|
|
218
313
|
end
|
|
219
314
|
end
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
class LiteralSuper
|
|
318
|
+
def initialize(args)
|
|
319
|
+
@args = args
|
|
224
320
|
end
|
|
225
|
-
def
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
else
|
|
229
|
-
ctx.out << "super(#{@vars.join(',')})"
|
|
230
|
-
end
|
|
321
|
+
def preprocess(ctx) end
|
|
322
|
+
def generate(ctx, source)
|
|
323
|
+
source << "[super rule_#{ctx.rule.name}:ctx];\n"
|
|
231
324
|
end
|
|
232
325
|
end
|
|
233
|
-
|
|
234
|
-
class
|
|
235
|
-
def
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
def gen_ruby(ctx)
|
|
239
|
-
#name = "caller.find{|c|n = c.to_s.scan(/`rule_(.*)'/).flatten.first; break n if n}.to_sym"
|
|
240
|
-
name = ctx.rule
|
|
241
|
-
ctx.out << "apply(:#{name}#{@vars.map{|v|",#{v}"}})"
|
|
326
|
+
|
|
327
|
+
class LiteralEnd
|
|
328
|
+
def preprocess(ctx) end
|
|
329
|
+
def generate(ctx, source)
|
|
330
|
+
source << "ctx->act_end();\n";
|
|
242
331
|
end
|
|
243
332
|
end
|
|
244
|
-
|
|
245
|
-
class
|
|
246
|
-
def initialize(
|
|
247
|
-
@
|
|
248
|
-
@rule = rule
|
|
333
|
+
|
|
334
|
+
class LiteralApply
|
|
335
|
+
def initialize(name, args)
|
|
336
|
+
@name = name
|
|
249
337
|
@args = args
|
|
250
338
|
end
|
|
251
|
-
def
|
|
252
|
-
|
|
339
|
+
def preprocess(ctx) end
|
|
340
|
+
def generate(ctx, source)
|
|
341
|
+
source << "ctx->apply(@selector(rule_#{@name}:));\n"
|
|
253
342
|
end
|
|
254
343
|
end
|
|
255
|
-
|
|
344
|
+
|
|
345
|
+
|
|
256
346
|
class LiteralQuotedToken
|
|
257
347
|
def initialize(str)
|
|
258
348
|
@str = str
|
|
259
349
|
end
|
|
260
|
-
def
|
|
261
|
-
|
|
350
|
+
def preprocess(ctx) end
|
|
351
|
+
def generate(ctx, source)
|
|
352
|
+
str, str_len = Generator.escape_quoated_string(@str)
|
|
353
|
+
if str_len == 1
|
|
354
|
+
# FIXME multibyte character optimize
|
|
355
|
+
source << "ctx->act_char(\"#{str}\",#{str_len});\n"
|
|
356
|
+
else
|
|
357
|
+
source << "ctx->act_token(\"#{str}\",#{str_len});\n"
|
|
358
|
+
end
|
|
262
359
|
end
|
|
263
360
|
end
|
|
264
|
-
|
|
361
|
+
|
|
265
362
|
class LiteralToken
|
|
266
363
|
def initialize(str)
|
|
267
364
|
@str = str
|
|
268
365
|
end
|
|
269
|
-
def
|
|
270
|
-
|
|
366
|
+
def preprocess(ctx) end
|
|
367
|
+
def generate(ctx, source)
|
|
368
|
+
str = @str
|
|
369
|
+
str_len = Generator.string_length(str)
|
|
370
|
+
if str_len == 1
|
|
371
|
+
# FIXME multibyte character optimize
|
|
372
|
+
source << "ctx->act_char(\"#{str}\",#{str_len});\n"
|
|
373
|
+
else
|
|
374
|
+
source << "ctx->act_token(\"#{str}\",#{str_len});\n"
|
|
375
|
+
end
|
|
271
376
|
end
|
|
272
377
|
end
|
|
273
|
-
|
|
274
|
-
class
|
|
378
|
+
|
|
379
|
+
class LiteralCharclass
|
|
275
380
|
def initialize(set)
|
|
276
381
|
@set = set
|
|
277
382
|
end
|
|
278
|
-
def
|
|
279
|
-
|
|
383
|
+
def preprocess(ctx) end
|
|
384
|
+
def generate(ctx, source)
|
|
385
|
+
set, set_len = Generator.escape_quoated_string(@set)
|
|
386
|
+
reg = "[" << set << "]" # FIXME \\A
|
|
387
|
+
reg_len = set_len + 2
|
|
388
|
+
# FIXME regexp precompile
|
|
389
|
+
source << "ctx->act_charclass(\"#{reg}\",#{reg_len});\n"
|
|
280
390
|
end
|
|
281
391
|
end
|
|
282
|
-
|
|
392
|
+
|
|
283
393
|
class LiteralAny
|
|
284
|
-
def
|
|
285
|
-
|
|
394
|
+
def preprocess(ctx) end
|
|
395
|
+
def generate(ctx, source)
|
|
396
|
+
source << "ctx->act_any();\n"
|
|
286
397
|
end
|
|
287
398
|
end
|
|
288
|
-
|
|
289
|
-
class
|
|
290
|
-
def initialize(
|
|
291
|
-
@
|
|
399
|
+
|
|
400
|
+
class Action
|
|
401
|
+
def initialize(code)
|
|
402
|
+
@code = code
|
|
292
403
|
end
|
|
293
|
-
def
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
404
|
+
def preprocess(ctx) end
|
|
405
|
+
def generate(ctx, source)
|
|
406
|
+
code, code_len = Generator.escape_quoated_string(@code)
|
|
407
|
+
source << "ctx->act_run(env,\"#{code}\",#{code_len});\n"
|
|
297
408
|
end
|
|
298
409
|
end
|
|
299
|
-
|
|
300
|
-
class
|
|
301
|
-
def initialize(
|
|
302
|
-
@
|
|
410
|
+
|
|
411
|
+
class Where
|
|
412
|
+
def initialize(code)
|
|
413
|
+
@code = code
|
|
303
414
|
end
|
|
304
|
-
def
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
415
|
+
def preprocess(ctx) end
|
|
416
|
+
def generate(ctx, source)
|
|
417
|
+
code, code_len = Generator.escape_quoated_string(@code)
|
|
418
|
+
source << "ctx->act_where(env,\"#{code}\",#{code_len});\n"
|
|
308
419
|
end
|
|
309
420
|
end
|
|
310
|
-
|
|
421
|
+
|
|
311
422
|
end
|
|
312
423
|
end
|
|
313
424
|
|
|
314
|
-
|