liquidscript 0.4.1 → 0.5.0
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.
- checksums.yaml +4 -4
- data/lib/liquidscript/buffer.rb +2 -2
- data/lib/liquidscript/compiler/icr.rb +1 -0
- data/lib/liquidscript/compiler/icr/classes.rb +11 -3
- data/lib/liquidscript/compiler/icr/expressions.rb +56 -10
- data/lib/liquidscript/compiler/icr/functions.rb +7 -6
- data/lib/liquidscript/compiler/icr/heredoc.rb +28 -0
- data/lib/liquidscript/compiler/icr/literals.rb +102 -9
- data/lib/liquidscript/errors.rb +6 -0
- data/lib/liquidscript/generator/base.rb +1 -1
- data/lib/liquidscript/generator/base/replacements.rb +2 -2
- data/lib/liquidscript/generator/javascript.rb +21 -0
- data/lib/liquidscript/generator/javascript/exceptions.rb +42 -0
- data/lib/liquidscript/generator/javascript/literals.rb +71 -9
- data/lib/liquidscript/generator/javascript/metas.rb +14 -13
- data/lib/liquidscript/generator/javascript/objects.rb +21 -16
- data/lib/liquidscript/icr/set.rb +8 -0
- data/lib/liquidscript/scanner/base/lexer.rb +13 -10
- data/lib/liquidscript/scanner/liquidscript.rb +95 -17
- data/lib/liquidscript/template.rb +1 -2
- data/lib/liquidscript/version.rb +1 -1
- data/liquidscript.gemspec +1 -0
- data/spec/fixtures/class.compile.yml +12 -1
- data/spec/fixtures/class.generate.yml +4 -4
- data/spec/fixtures/combination.generate.yml +4 -4
- data/spec/fixtures/complex.generate.yml +5 -5
- data/spec/fixtures/expression.generate.yml +1 -1
- data/spec/fixtures/heredoc.generate.yml +9 -0
- data/spec/fixtures/literals.generate.yml +9 -1
- data/spec/fixtures/loop.generate.yml +16 -0
- data/spec/fixtures/main.compile.yml +19 -15
- data/spec/fixtures/operator.generate.yml +10 -2
- data/spec/fixtures/string.compile.yml +20 -1
- data/spec/fixtures/string.generate.yml +1 -1
- data/spec/fixtures/underscore.js +28 -0
- data/spec/fixtures/underscore.ls +2 -1
- data/spec/liquidscript/compiler/icr_spec.rb +2 -0
- data/spec/liquidscript/node_spec.rb +21 -0
- data/spec/liquidscript/scanner/lexer_spec.rb +23 -2
- data/spec/support/matchers/compile.rb +1 -1
- data/spec/support/matchers/generate.rb +6 -3
- data/spec/support/matchers/run.rb +12 -0
- metadata +28 -2
@@ -0,0 +1,42 @@
|
|
1
|
+
module Liquidscript
|
2
|
+
module Generator
|
3
|
+
class Javascript < Base
|
4
|
+
module Exceptions
|
5
|
+
|
6
|
+
def generate_try(code)
|
7
|
+
out = buffer
|
8
|
+
out << "try {\n"
|
9
|
+
insert_into(code[1], out)
|
10
|
+
out << indent_level << "}"
|
11
|
+
|
12
|
+
if code[2]
|
13
|
+
out << replace(code[2])
|
14
|
+
end
|
15
|
+
|
16
|
+
out
|
17
|
+
end
|
18
|
+
|
19
|
+
def generate_catch(code)
|
20
|
+
out = buffer
|
21
|
+
out << "catch(#{code[1].value}) {\n"
|
22
|
+
insert_into(code[2], out)
|
23
|
+
out << indent_level << "}"
|
24
|
+
|
25
|
+
if code[3]
|
26
|
+
out << replace(code[3])
|
27
|
+
end
|
28
|
+
|
29
|
+
out
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate_finally(code)
|
33
|
+
out = buffer
|
34
|
+
out << "finally {\n"
|
35
|
+
insert_into(code[1], out)
|
36
|
+
out << indent_level << "}"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -4,19 +4,60 @@ module Liquidscript
|
|
4
4
|
module Literals
|
5
5
|
|
6
6
|
BINOP_SWITCH = {
|
7
|
-
"=="
|
7
|
+
"==" => "===",
|
8
8
|
"===" => "==",
|
9
|
-
"!="
|
9
|
+
"!=" => "!==",
|
10
10
|
"!==" => "!=",
|
11
|
-
"or"
|
11
|
+
"or" => "||",
|
12
12
|
"and" => "&&"
|
13
13
|
}.freeze
|
14
14
|
|
15
15
|
def generate_number(code)
|
16
|
-
|
17
16
|
"#{code.first}"
|
18
17
|
end
|
19
18
|
|
19
|
+
def generate_action(code)
|
20
|
+
code[1].value
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate_op(code)
|
24
|
+
if code[1].type == :variable
|
25
|
+
"#{code[1].name}#{code[2].value}"
|
26
|
+
else
|
27
|
+
"#{replace(code[1])}#{code[2].value}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate_while(code)
|
32
|
+
loop_body = buffer
|
33
|
+
loop_body << "while(#{replace(code[1])}) {\n"
|
34
|
+
insert_into(code[2], loop_body)
|
35
|
+
loop_body << indent_level << "}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def generate_for_in(code)
|
39
|
+
loop_body = buffer
|
40
|
+
loop_body << "for(#{code[1].value} in #{code[2].name}) {\n"
|
41
|
+
insert_into(code[3], loop_body)
|
42
|
+
loop_body << indent_level << "}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def generate_for_seg(code)
|
46
|
+
loop_body = buffer
|
47
|
+
loop_body << "for(" <<
|
48
|
+
replace(code[1]) << ";" <<
|
49
|
+
replace(code[2]) << ";" <<
|
50
|
+
replace(code[3]) << ") {\n"
|
51
|
+
|
52
|
+
insert_into(code[4], loop_body)
|
53
|
+
|
54
|
+
loop_body << indent_level << "}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def generate_regex(code)
|
58
|
+
"/#{code[1].value[0]}/#{code[1].value[1]}"
|
59
|
+
end
|
60
|
+
|
20
61
|
def generate_istring(code)
|
21
62
|
"\"#{code.first.gsub("\n", "\\n")}\""
|
22
63
|
end
|
@@ -24,18 +65,17 @@ module Liquidscript
|
|
24
65
|
def generate_interop(code)
|
25
66
|
content = code[1..-1]
|
26
67
|
buf = buffer
|
27
|
-
buf.set_join! ','
|
28
68
|
|
29
69
|
content.each do |part|
|
30
70
|
case part.type
|
31
71
|
when :istring_begin, :istring
|
32
72
|
buf << "\"#{part.value}\""
|
33
73
|
else
|
34
|
-
buf << "#{replace(part)}"
|
74
|
+
buf << " + (#{replace(part)}) + "
|
35
75
|
end
|
36
76
|
end
|
37
77
|
|
38
|
-
|
78
|
+
buf
|
39
79
|
end
|
40
80
|
|
41
81
|
def generate_sstring(code)
|
@@ -47,6 +87,22 @@ module Liquidscript
|
|
47
87
|
" #{code[1].value} #{replace(code[2])}"
|
48
88
|
end
|
49
89
|
|
90
|
+
def generate_href(code)
|
91
|
+
heredoc = code[1]
|
92
|
+
hbuf = buffer
|
93
|
+
|
94
|
+
heredoc.body.each do |part|
|
95
|
+
case part.type
|
96
|
+
when :heredoc, :iheredoc, :iheredoc_begin
|
97
|
+
hbuf << '"' << part.value.gsub('"', '\\"') << '"'
|
98
|
+
else
|
99
|
+
hbuf << ' + ' << replace(part) << ' + '
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
hbuf
|
104
|
+
end
|
105
|
+
|
50
106
|
def generate_binop(code)
|
51
107
|
op = BINOP_SWITCH.fetch(code[1].value) do
|
52
108
|
code[1].value
|
@@ -63,11 +119,13 @@ module Liquidscript
|
|
63
119
|
|
64
120
|
object = buffer
|
65
121
|
object.set_join! ', '
|
122
|
+
indent!
|
66
123
|
|
67
124
|
code[1].inject(object) do |buf, part|
|
68
|
-
buf << "\"#{part[0].value}\": #{replace(part[1])}"
|
125
|
+
buf << "#{indent_level}\"#{part[0].value}\": #{replace(part[1])}"
|
69
126
|
end
|
70
127
|
|
128
|
+
unindent!
|
71
129
|
"{#{object}}"
|
72
130
|
end
|
73
131
|
|
@@ -84,12 +142,13 @@ module Liquidscript
|
|
84
142
|
end
|
85
143
|
|
86
144
|
def generate_newline(_)
|
87
|
-
"
|
145
|
+
""
|
88
146
|
end
|
89
147
|
|
90
148
|
def generate_function(code)
|
91
149
|
|
92
150
|
function = buffer
|
151
|
+
indent!
|
93
152
|
|
94
153
|
function <<
|
95
154
|
"function(" <<
|
@@ -97,6 +156,9 @@ module Liquidscript
|
|
97
156
|
') {' <<
|
98
157
|
replace(code[1]) <<
|
99
158
|
'}'
|
159
|
+
|
160
|
+
unindent!
|
161
|
+
function
|
100
162
|
end
|
101
163
|
end
|
102
164
|
end
|
@@ -6,18 +6,15 @@ module Liquidscript
|
|
6
6
|
def generate_exec(code)
|
7
7
|
exec = buffer
|
8
8
|
exec << _exec_context(code)
|
9
|
-
code.codes
|
10
|
-
m << replace(c)
|
11
|
-
m
|
12
|
-
end
|
9
|
+
insert_into(code.codes, exec)
|
13
10
|
end
|
14
11
|
|
15
12
|
def generate_set(code)
|
16
13
|
case code[1].type
|
17
14
|
when :variable
|
18
|
-
"#{code[1].name} = #{replace code[2]}
|
15
|
+
"#{code[1].name} = #{replace code[2]}"
|
19
16
|
when :property
|
20
|
-
"#{replace code[1]} = #{replace code[2]}
|
17
|
+
"#{replace code[1]} = #{replace code[2]}"
|
21
18
|
end
|
22
19
|
end
|
23
20
|
|
@@ -31,9 +28,11 @@ module Liquidscript
|
|
31
28
|
|
32
29
|
define_method(:"generate_#{k}") do |code|
|
33
30
|
part = buffer
|
34
|
-
part << "
|
35
|
-
|
36
|
-
part
|
31
|
+
part << "#{v % replace(code[1])} {\n"
|
32
|
+
indent!
|
33
|
+
insert_into(code[2], part)
|
34
|
+
unindent!
|
35
|
+
part << indent_level << "}"
|
37
36
|
|
38
37
|
if code[3]
|
39
38
|
part << replace(code[3])
|
@@ -45,9 +44,11 @@ module Liquidscript
|
|
45
44
|
|
46
45
|
def generate_else(code)
|
47
46
|
part = buffer
|
48
|
-
part << "
|
49
|
-
|
50
|
-
part
|
47
|
+
part << " else {\n"
|
48
|
+
indent!
|
49
|
+
insert_into(code[1], part)
|
50
|
+
unindent!
|
51
|
+
part << indent_level << "}"
|
51
52
|
end
|
52
53
|
|
53
54
|
protected
|
@@ -55,7 +56,7 @@ module Liquidscript
|
|
55
56
|
def _exec_context(code)
|
56
57
|
|
57
58
|
unless code.locals.empty?
|
58
|
-
"var #{code.locals.join(',')}
|
59
|
+
"\n#{indent_level}var #{code.locals.join(',')};\n"
|
59
60
|
end
|
60
61
|
end
|
61
62
|
end
|
@@ -38,7 +38,7 @@ module Liquidscript
|
|
38
38
|
prop << replace(code[1])
|
39
39
|
end
|
40
40
|
|
41
|
-
prop << "." << code[2]
|
41
|
+
prop << "." << code[2]
|
42
42
|
end
|
43
43
|
|
44
44
|
def generate_class(code)
|
@@ -46,23 +46,29 @@ module Liquidscript
|
|
46
46
|
class_name = code[1].value
|
47
47
|
|
48
48
|
in_module(class_name) do |last_module|
|
49
|
-
body.block <<-JS
|
49
|
+
body.block 7 - @indent, <<-JS
|
50
50
|
#{class_name} = #{class_name} || function #{class_name}() {
|
51
51
|
if(this.initialize) {
|
52
52
|
this.initialize.apply(this, arguments);
|
53
53
|
}
|
54
|
-
}
|
54
|
+
}
|
55
55
|
JS
|
56
56
|
|
57
|
-
code[2]
|
57
|
+
if code[2]
|
58
|
+
body.block 8 - @indent, <<-JS
|
59
|
+
#{class_name}.prototype.__proto__ = #{code[2].value};
|
60
|
+
JS
|
61
|
+
end
|
62
|
+
|
63
|
+
code[3].each do |part|
|
58
64
|
k, v = part
|
59
65
|
case k.type
|
60
66
|
when :identifier
|
61
|
-
body.block <<-JS
|
67
|
+
body.block 8 - @indent, <<-JS
|
62
68
|
#{class_name}.prototype.#{k.value} = #{replace(v)};
|
63
69
|
JS
|
64
|
-
when :
|
65
|
-
body.block <<-JS
|
70
|
+
when :istring
|
71
|
+
body.block 8 - @indent, <<-JS
|
66
72
|
#{class_name}.prototype[#{k.value}] = #{replace(v)};
|
67
73
|
JS
|
68
74
|
when :property
|
@@ -70,9 +76,8 @@ module Liquidscript
|
|
70
76
|
raise InvalidCodeError.new(k[1].value)
|
71
77
|
end
|
72
78
|
|
73
|
-
body.block <<-JS
|
74
|
-
#{class_name}.#{k[2]
|
75
|
-
#{replace(v)};
|
79
|
+
body.block 8 - @indent, <<-JS
|
80
|
+
#{class_name}.#{k[2]} = #{replace(v)};
|
76
81
|
JS
|
77
82
|
when :class
|
78
83
|
body << generate_class(part)
|
@@ -82,8 +87,8 @@ module Liquidscript
|
|
82
87
|
end
|
83
88
|
|
84
89
|
if last_module
|
85
|
-
body.block <<-JS
|
86
|
-
#{last_module}.#{class_name} = #{class_name}
|
90
|
+
body.block 7, <<-JS
|
91
|
+
#{last_module}.#{class_name} = #{class_name}
|
87
92
|
JS
|
88
93
|
end
|
89
94
|
|
@@ -103,11 +108,11 @@ module Liquidscript
|
|
103
108
|
k, v = part
|
104
109
|
case k
|
105
110
|
when :identifier
|
106
|
-
body.block <<-JS
|
111
|
+
body.block 8, <<-JS
|
107
112
|
#{module_name}.#{k.value} = #{replace(v)};
|
108
113
|
JS
|
109
114
|
when :dstring
|
110
|
-
body.block <<-JS
|
115
|
+
body.block 8, <<-JS
|
111
116
|
#{module_name}[#{k.value}] = #{replace(v)};
|
112
117
|
JS
|
113
118
|
when :class
|
@@ -118,8 +123,8 @@ module Liquidscript
|
|
118
123
|
end
|
119
124
|
|
120
125
|
if last_module
|
121
|
-
body.block <<-JS
|
122
|
-
#{last_module}.#{module_name} = #{module_name}
|
126
|
+
body.block 7, <<-JS
|
127
|
+
#{last_module}.#{module_name} = #{module_name}
|
123
128
|
JS
|
124
129
|
end
|
125
130
|
end
|
data/lib/liquidscript/icr/set.rb
CHANGED
@@ -43,6 +43,14 @@ module Liquidscript
|
|
43
43
|
@code << Code.new(action, arguments)
|
44
44
|
end
|
45
45
|
|
46
|
+
def <<(*v)
|
47
|
+
v.select { |p| p }.each do |part|
|
48
|
+
@code << part
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
alias_method :push, :<<
|
53
|
+
|
46
54
|
# A list of all the local variables in the
|
47
55
|
# current scope. Local variables are defined
|
48
56
|
# as variables that were a) not passed in by
|
@@ -7,18 +7,20 @@ module Liquidscript
|
|
7
7
|
key, value = context.find_matcher(scanner)
|
8
8
|
|
9
9
|
if value.nil? && scanner.rest?
|
10
|
-
error scanner
|
10
|
+
error scanner, context
|
11
11
|
end
|
12
12
|
|
13
13
|
normalize_action key, value, scanner if scanner.rest?
|
14
14
|
end
|
15
15
|
|
16
|
-
def lex(
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
def lex(*args)
|
17
|
+
args.flatten!
|
18
|
+
to_lex = args.pop
|
19
|
+
|
20
|
+
context, body = if to_lex.is_a? Hash
|
21
|
+
to_lex.to_a.first
|
20
22
|
else
|
21
|
-
|
23
|
+
[to_lex, nil]
|
22
24
|
end
|
23
25
|
|
24
26
|
scanner = if body
|
@@ -29,7 +31,7 @@ module Liquidscript
|
|
29
31
|
out = []
|
30
32
|
|
31
33
|
context = find_context(context)
|
32
|
-
instance_exec &context.init
|
34
|
+
instance_exec(*args, &context.init)
|
33
35
|
|
34
36
|
while scanner.rest? && out.last != EXIT
|
35
37
|
out << perform_with_context(context, scanner)
|
@@ -38,8 +40,9 @@ module Liquidscript
|
|
38
40
|
out
|
39
41
|
end
|
40
42
|
|
41
|
-
def error(scanner = @scanner)
|
42
|
-
raise SyntaxError, "Unexpected
|
43
|
+
def error(scanner = @scanner, context = @context)
|
44
|
+
raise SyntaxError, "Unexpected " +
|
45
|
+
"#{scanner.matched}#{scanner.peek(2)}".inspect +
|
43
46
|
" (line: #{line}, column: #{column})"
|
44
47
|
end
|
45
48
|
|
@@ -68,7 +71,7 @@ module Liquidscript
|
|
68
71
|
when Proc
|
69
72
|
instance_exec(*body.match(key), &value)
|
70
73
|
when Symbol
|
71
|
-
lex value
|
74
|
+
lex(*body.match(key), value)
|
72
75
|
when EXIT
|
73
76
|
EXIT
|
74
77
|
end
|
@@ -30,16 +30,23 @@ module Liquidscript
|
|
30
30
|
new
|
31
31
|
return
|
32
32
|
typeof
|
33
|
+
throw
|
34
|
+
)
|
35
|
+
|
36
|
+
set :actions, %w(
|
37
|
+
break
|
38
|
+
continue
|
33
39
|
)
|
34
40
|
|
35
41
|
set :binops, %w(
|
36
|
-
+ - * /
|
42
|
+
+ - * / ^
|
37
43
|
<< >> >>>
|
38
44
|
== ===
|
39
45
|
!= !==
|
40
46
|
> >=
|
41
47
|
< <=
|
42
48
|
&& ||
|
49
|
+
& |
|
43
50
|
instanceof
|
44
51
|
or and
|
45
52
|
)
|
@@ -59,43 +66,59 @@ module Liquidscript
|
|
59
66
|
on("unless") { emit :unless }
|
60
67
|
on("elsif") { emit :elsif }
|
61
68
|
on("else") { emit :else }
|
69
|
+
on("for") { emit :for }
|
70
|
+
on("while") { emit :while }
|
71
|
+
on("try") { emit :try }
|
72
|
+
on("catch") { emit :catch }
|
73
|
+
on("finally") { emit :finally }
|
62
74
|
on(:number) { |m| emit :number, m }
|
63
75
|
on(:string) { |m| emit :sstring, m }
|
64
76
|
on(:keywords) { |m| emit :keyword, m }
|
65
|
-
on(:
|
77
|
+
on(:actions) { |m| emit :action, m }
|
66
78
|
on("->") { emit :arrow }
|
67
79
|
on("=") { emit :equal }
|
68
|
-
on("{") { emit :
|
80
|
+
on("{") { emit :lbrace }
|
69
81
|
on("(") { emit :lparen }
|
70
|
-
on("[") { emit :
|
71
|
-
on("}") { emit :
|
82
|
+
on("[") { emit :lbrack }
|
83
|
+
on("}") { emit :rbrace }
|
72
84
|
on(")") { emit :rparen }
|
73
|
-
on("]") { emit :
|
85
|
+
on("]") { emit :rbrack }
|
74
86
|
on(":") { emit :colon }
|
75
87
|
on(".") { emit :prop }
|
76
88
|
on(",") { emit :comma }
|
77
|
-
on("\n") { line
|
89
|
+
on("\n") { line! }
|
90
|
+
on(%r{"} => :istring)
|
91
|
+
on(%r{<<([A-Z]+)}) do |_, s|
|
92
|
+
emit :heredoc_ref, s
|
93
|
+
@lexes << [:heredoc, s]
|
94
|
+
end
|
95
|
+
on(%r{<<-([A-Z]+)}) do |_, s|
|
96
|
+
emit :iheredoc_ref, s
|
97
|
+
@lexes << [:iheredoc, s]
|
98
|
+
end
|
99
|
+
on(%r{/(.*?)/([a-z]*)}) { |_, m, b|
|
100
|
+
emit :regex, [m, b]
|
101
|
+
}
|
102
|
+
on("///" => :block_regex)
|
78
103
|
on(:binops) { |m| emit :binop, m }
|
104
|
+
on(:unops) { |m| emit :unop, m }
|
79
105
|
on(:identifier) { |m| emit :identifier, m }
|
80
106
|
|
81
|
-
on(
|
82
|
-
on(
|
83
|
-
on(
|
84
|
-
on(:_) { error }
|
107
|
+
on(%r{#.*?\n}) { }
|
108
|
+
on(%r{\s}) { }
|
109
|
+
on(:_) { |m| error }
|
85
110
|
end
|
86
111
|
|
87
112
|
context :istring do
|
88
|
-
init
|
89
|
-
@buffer = []
|
90
|
-
end
|
113
|
+
init { @buffer = [] }
|
91
114
|
|
92
|
-
on(
|
93
|
-
on(
|
115
|
+
on('\\"') { |m| @buffer << m }
|
116
|
+
on('"') do
|
94
117
|
emit :istring, @buffer.join
|
95
118
|
exit
|
96
119
|
end
|
97
120
|
|
98
|
-
on(
|
121
|
+
on(%r{\#\{(.*?)\}}) do |_, b|
|
99
122
|
emit :istring_begin, @buffer.join
|
100
123
|
lex :main => b
|
101
124
|
@buffer = []
|
@@ -103,17 +126,72 @@ module Liquidscript
|
|
103
126
|
|
104
127
|
on(:_) { |m| @buffer << m }
|
105
128
|
end
|
129
|
+
|
130
|
+
context :heredoc do
|
131
|
+
init { @buffer = [] }
|
132
|
+
|
133
|
+
on(%r{\n\s*([A-Z]+)\s*\n}) do |_, s|
|
134
|
+
if @start == s
|
135
|
+
emit :heredoc, @buffer.join
|
136
|
+
exit
|
137
|
+
else
|
138
|
+
@buffer << _
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
on(:_) { |m| @buffer << m }
|
143
|
+
end
|
144
|
+
|
145
|
+
context :iheredoc do
|
146
|
+
init { @buffer = [] }
|
147
|
+
|
148
|
+
on(%r{\n\s*([A-Z]+)\s*\n}) do |_, s|
|
149
|
+
if @start == s
|
150
|
+
emit :iheredoc, @buffer.join
|
151
|
+
@start = nil
|
152
|
+
exit
|
153
|
+
else
|
154
|
+
@buffer << _
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
on(%r{\#\{(.*?)\}}) do |_, b|
|
159
|
+
emit :iheredoc_begin, @buffer.join
|
160
|
+
lex :main => b
|
161
|
+
@buffer = []
|
162
|
+
end
|
163
|
+
|
164
|
+
on(:_) { |m| @buffer << m }
|
165
|
+
end
|
166
|
+
|
167
|
+
context :block_regex do
|
168
|
+
init { @buffer = [] }
|
169
|
+
|
170
|
+
on(%r{///([a-z]*)}) do |_, m|
|
171
|
+
emit :regex, [@buffer.join, m]
|
172
|
+
exit
|
173
|
+
end
|
174
|
+
on(%r{#.*?\n}) { }
|
175
|
+
on("\n") { }
|
176
|
+
on(:_) { |m| @buffer << m }
|
177
|
+
end
|
106
178
|
end
|
107
179
|
|
108
180
|
def initialize(*)
|
109
181
|
@line = 1
|
110
182
|
@cstart = 0
|
183
|
+
@lexes = []
|
111
184
|
super
|
112
185
|
end
|
113
186
|
|
114
187
|
def line!
|
115
188
|
@line += 1
|
116
189
|
@cstart = @scanner.pos
|
190
|
+
while @lexes.any?
|
191
|
+
type, @start = @lexes.shift
|
192
|
+
|
193
|
+
lex type
|
194
|
+
end
|
117
195
|
end
|
118
196
|
|
119
197
|
def line
|