interscript 2.1.0 → 2.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +6 -0
- data/Rakefile +9 -1
- data/bin/console +4 -8
- data/interscript.gemspec +2 -1
- data/lib/interscript.rb +78 -0
- data/lib/interscript/compiler/javascript.rb +6 -1
- data/lib/interscript/compiler/ruby.rb +5 -0
- data/lib/interscript/detector.rb +62 -0
- data/lib/interscript/dsl.rb +35 -2
- data/lib/interscript/dsl/document.rb +2 -1
- data/lib/interscript/dsl/group.rb +7 -6
- data/lib/interscript/dsl/group/parallel.rb +2 -2
- data/lib/interscript/dsl/tests.rb +2 -2
- data/lib/interscript/interpreter.rb +5 -1
- data/lib/interscript/node.rb +4 -0
- data/lib/interscript/node/alias_def.rb +6 -0
- data/lib/interscript/node/dependency.rb +16 -0
- data/lib/interscript/node/document.rb +34 -0
- data/lib/interscript/node/group.rb +13 -2
- data/lib/interscript/node/item.rb +4 -0
- data/lib/interscript/node/item/alias.rb +12 -0
- data/lib/interscript/node/item/any.rb +7 -0
- data/lib/interscript/node/item/capture.rb +11 -0
- data/lib/interscript/node/item/group.rb +29 -1
- data/lib/interscript/node/item/repeat.rb +4 -0
- data/lib/interscript/node/item/stage.rb +4 -0
- data/lib/interscript/node/item/string.rb +7 -0
- data/lib/interscript/node/metadata.rb +10 -0
- data/lib/interscript/node/rule.rb +3 -0
- data/lib/interscript/node/rule/funcall.rb +12 -2
- data/lib/interscript/node/rule/run.rb +16 -3
- data/lib/interscript/node/rule/sub.rb +165 -4
- data/lib/interscript/node/stage.rb +30 -4
- data/lib/interscript/node/tests.rb +10 -0
- data/lib/interscript/stdlib.rb +45 -3
- data/lib/interscript/utils/helpers.rb +39 -0
- data/lib/interscript/version.rb +1 -1
- data/lib/interscript/visualize/json.rb +12 -4
- metadata +17 -1
data/lib/interscript/node.rb
CHANGED
@@ -4,6 +4,22 @@ class Interscript::Node::Dependency < Interscript::Node
|
|
4
4
|
def initialize
|
5
5
|
end
|
6
6
|
|
7
|
+
def reverse
|
8
|
+
rdep = self.class.new
|
9
|
+
rdep.name = name
|
10
|
+
rdep.full_name = Interscript::Node::Document.reverse_name(full_name)
|
11
|
+
rdep.import = import
|
12
|
+
rdep.document = document&.reverse
|
13
|
+
rdep
|
14
|
+
end
|
15
|
+
|
16
|
+
def ==(other)
|
17
|
+
super &&
|
18
|
+
self.full_name == other.full_name &&
|
19
|
+
self.import == other.import &&
|
20
|
+
self.name == other.name
|
21
|
+
end
|
22
|
+
|
7
23
|
def to_hash
|
8
24
|
{ :class => self.class.to_s,
|
9
25
|
:name => @name,
|
@@ -1,6 +1,7 @@
|
|
1
1
|
class Interscript::Node::Document
|
2
2
|
attr_accessor :metadata, :tests, :name
|
3
3
|
attr_accessor :dependencies, :aliases, :stages, :dep_aliases
|
4
|
+
attr_accessor :reversed_from
|
4
5
|
|
5
6
|
def initialize
|
6
7
|
puts "Interscript::Node::Document.new " if $DEBUG
|
@@ -34,6 +35,39 @@ class Interscript::Node::Document
|
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
38
|
+
def reverse
|
39
|
+
@reverse ||= self.class.new.tap do |rdoc|
|
40
|
+
rdoc.name = self.class.reverse_name(name)
|
41
|
+
rdoc.metadata = metadata&.reverse
|
42
|
+
rdoc.tests = tests&.reverse
|
43
|
+
rdoc.dependencies = dependencies.map(&:reverse)
|
44
|
+
rdoc.stages = stages.transform_values(&:reverse)
|
45
|
+
rdoc.dep_aliases = dep_aliases.transform_values(&:reverse)
|
46
|
+
rdoc.aliases = aliases
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.reverse_name(name)
|
51
|
+
newname = (name || "noname").split("-")
|
52
|
+
newname[2], newname[3] = newname[3], newname[2] if newname.length >= 4
|
53
|
+
newname = newname.join("-")
|
54
|
+
if newname == name
|
55
|
+
newname.gsub!("-reverse", "")
|
56
|
+
end
|
57
|
+
if newname == name
|
58
|
+
newname += "-reverse"
|
59
|
+
end
|
60
|
+
newname
|
61
|
+
end
|
62
|
+
|
63
|
+
def ==(other)
|
64
|
+
self.class == other.class &&
|
65
|
+
self.metadata == other.metadata &&
|
66
|
+
self.tests == other.tests &&
|
67
|
+
self.stages == other.stages &&
|
68
|
+
self.aliases == other.aliases
|
69
|
+
end
|
70
|
+
|
37
71
|
def to_hash
|
38
72
|
{ :class => self.class.to_s, :metadata => @metadata&.to_hash,
|
39
73
|
:tests => @tests&.to_hash,
|
@@ -1,7 +1,8 @@
|
|
1
1
|
class Interscript::Node::Group < Interscript::Node
|
2
|
-
attr_accessor :children
|
2
|
+
attr_accessor :children, :reverse_run
|
3
3
|
|
4
|
-
def initialize
|
4
|
+
def initialize(reverse_run: nil)
|
5
|
+
@reverse_run = reverse_run
|
5
6
|
@children = []
|
6
7
|
end
|
7
8
|
|
@@ -20,11 +21,21 @@ class Interscript::Node::Group < Interscript::Node
|
|
20
21
|
self
|
21
22
|
end
|
22
23
|
|
24
|
+
def reverse
|
25
|
+
self.class.new(reverse_run: reverse_run.nil? ? nil : !reverse_run).tap do |r|
|
26
|
+
r.children = self.children.reverse.map(&:reverse)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
23
30
|
def to_hash
|
24
31
|
{ :class => self.class.to_s,
|
25
32
|
:children => @children.map{|x| x.to_hash} }
|
26
33
|
end
|
27
34
|
|
35
|
+
def ==(other)
|
36
|
+
super && self.children == other.children && self.reverse_run == other.reverse_run
|
37
|
+
end
|
38
|
+
|
28
39
|
def inspect
|
29
40
|
@children.map(&:inspect).join("\n").gsub(/^/, " ")
|
30
41
|
end
|
@@ -36,6 +36,10 @@ class Interscript::Node::Item < Interscript::Node
|
|
36
36
|
:item => self.item }
|
37
37
|
end
|
38
38
|
|
39
|
+
def ==(other)
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
39
43
|
def self.try_convert(i)
|
40
44
|
i = Interscript::Node::Item::String.new(i) if i.class == ::String
|
41
45
|
raise TypeError, "Wrong type #{i.class}, expected I::Node::Item" unless Interscript::Node::Item === i
|
@@ -10,6 +10,10 @@ class Interscript::Node::Item::Alias < Interscript::Node::Item
|
|
10
10
|
!map && Interscript::Stdlib::ALIASES.has_key?(name)
|
11
11
|
end
|
12
12
|
|
13
|
+
def boundary_like?
|
14
|
+
Interscript::Stdlib.boundary_like_alias?(name)
|
15
|
+
end
|
16
|
+
|
13
17
|
def max_length
|
14
18
|
if stdlib?
|
15
19
|
([:none].include? name) ? 0 : 1
|
@@ -19,6 +23,10 @@ class Interscript::Node::Item::Alias < Interscript::Node::Item
|
|
19
23
|
end
|
20
24
|
end
|
21
25
|
|
26
|
+
# Not implemented properly
|
27
|
+
def downcase; self; end
|
28
|
+
def upcase; self; end
|
29
|
+
|
22
30
|
def first_string
|
23
31
|
self
|
24
32
|
end
|
@@ -32,6 +40,10 @@ class Interscript::Node::Item::Alias < Interscript::Node::Item
|
|
32
40
|
}
|
33
41
|
end
|
34
42
|
|
43
|
+
def ==(other)
|
44
|
+
super && self.name == other.name && self.map == other.map
|
45
|
+
end
|
46
|
+
|
35
47
|
def inspect
|
36
48
|
if map
|
37
49
|
"map.#{map}.#{name}"
|
@@ -25,6 +25,9 @@ class Interscript::Node::Item::Any < Interscript::Node::Item
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
def downcase; self.class.new(self.data.map(&:downcase)); end
|
29
|
+
def upcase; self.class.new(self.data.map(&:upcase)); end
|
30
|
+
|
28
31
|
def first_string
|
29
32
|
case @value
|
30
33
|
when Array
|
@@ -70,6 +73,10 @@ class Interscript::Node::Item::Any < Interscript::Node::Item
|
|
70
73
|
hash
|
71
74
|
end
|
72
75
|
|
76
|
+
def ==(other)
|
77
|
+
super && self.data == other.data
|
78
|
+
end
|
79
|
+
|
73
80
|
def inspect
|
74
81
|
"any(#{value.inspect})"
|
75
82
|
end
|
@@ -15,11 +15,18 @@ class Interscript::Node::Item::CaptureGroup < Interscript::Node::Item
|
|
15
15
|
data.nth_string
|
16
16
|
end
|
17
17
|
|
18
|
+
def downcase; self.dup.tap { |i| i.data = i.data.downcase }; end
|
19
|
+
def upcase; self.dup.tap { |i| i.data = i.data.upcase }; end
|
20
|
+
|
18
21
|
def to_hash
|
19
22
|
{ :class => self.class.to_s,
|
20
23
|
:data => self.data.to_hash }
|
21
24
|
end
|
22
25
|
|
26
|
+
def ==(other)
|
27
|
+
super && self.data == other.data
|
28
|
+
end
|
29
|
+
|
23
30
|
def inspect
|
24
31
|
"capture(#{@data.inspect})"
|
25
32
|
end
|
@@ -44,6 +51,10 @@ class Interscript::Node::Item::CaptureRef < Interscript::Node::Item
|
|
44
51
|
:id => self.id }
|
45
52
|
end
|
46
53
|
|
54
|
+
def ==(other)
|
55
|
+
super && self.id == other.id
|
56
|
+
end
|
57
|
+
|
47
58
|
def inspect
|
48
59
|
"ref(#{@id.inspect})"
|
49
60
|
end
|
@@ -10,11 +10,35 @@ class Interscript::Node::Item::Group < Interscript::Node::Item
|
|
10
10
|
def +(item)
|
11
11
|
item = Interscript::Node::Item.try_convert(item)
|
12
12
|
out = self.dup
|
13
|
-
|
13
|
+
if Interscript::Node::Item::Group === item
|
14
|
+
out.children += item.children
|
15
|
+
else
|
16
|
+
out.children << item
|
17
|
+
end
|
14
18
|
out.verify!
|
15
19
|
out
|
16
20
|
end
|
17
21
|
|
22
|
+
def compact
|
23
|
+
out = self.dup do |n|
|
24
|
+
n.children = n.children.reject do |i|
|
25
|
+
(Interscript::Node::Alias === i && i.name == :none) ||
|
26
|
+
(Interscript::Node::String === i && i.data == "")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
if out.children.count == 0
|
31
|
+
Interscript::Node::Alias.new(:none)
|
32
|
+
elsif out.children.count == 1
|
33
|
+
out.children.first
|
34
|
+
else
|
35
|
+
out
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def downcase; self.dup.tap { |i| i.children = i.children.map(&:downcase) }; end
|
40
|
+
def upcase; self.dup.tap { |i| i.children = i.children.map(&:upcase) }; end
|
41
|
+
|
18
42
|
# Verify if a group is valid
|
19
43
|
def verify!
|
20
44
|
wrong = @children.find do |i|
|
@@ -45,6 +69,10 @@ class Interscript::Node::Item::Group < Interscript::Node::Item
|
|
45
69
|
:children => self.children.map{|x| x.to_hash} }
|
46
70
|
end
|
47
71
|
|
72
|
+
def ==(other)
|
73
|
+
super && self.children == other.children
|
74
|
+
end
|
75
|
+
|
48
76
|
def inspect
|
49
77
|
@children.map(&:inspect).join("+")
|
50
78
|
end
|
@@ -17,6 +17,9 @@ class Interscript::Node::Item::String < Interscript::Node::Item
|
|
17
17
|
self.data
|
18
18
|
end
|
19
19
|
|
20
|
+
def downcase; self.dup.tap { |i| i.data = i.data.downcase }; end
|
21
|
+
def upcase; self.dup.tap { |i| i.data = i.data.upcase }; end
|
22
|
+
|
20
23
|
alias nth_string first_string
|
21
24
|
|
22
25
|
def + other
|
@@ -33,6 +36,10 @@ class Interscript::Node::Item::String < Interscript::Node::Item
|
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
39
|
+
def ==(other)
|
40
|
+
super && self.data == other.data
|
41
|
+
end
|
42
|
+
|
36
43
|
def inspect
|
37
44
|
@data.inspect
|
38
45
|
end
|
@@ -11,6 +11,16 @@ class Interscript::Node::MetaData < Interscript::Node
|
|
11
11
|
@data[k]
|
12
12
|
end
|
13
13
|
|
14
|
+
def reverse
|
15
|
+
self.class.new(data.dup, **{}).tap do |rmd|
|
16
|
+
rmd[:source_script], rmd[:destination_script] = rmd[:destination_script], rmd[:source_script]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def ==(other)
|
21
|
+
super && self.data == other.data
|
22
|
+
end
|
23
|
+
|
14
24
|
def to_hash
|
15
25
|
{:class => self.class.to_s,
|
16
26
|
:data => @data}
|
@@ -1,7 +1,8 @@
|
|
1
1
|
class Interscript::Node::Rule::Funcall < Interscript::Node::Rule
|
2
|
-
attr_accessor :name, :kwargs
|
3
|
-
def initialize name, **kwargs
|
2
|
+
attr_accessor :name, :kwargs, :reverse_run
|
3
|
+
def initialize name, reverse_run: nil, **kwargs
|
4
4
|
@name = name
|
5
|
+
@reverse_run = reverse_run
|
5
6
|
@kwargs = kwargs
|
6
7
|
end
|
7
8
|
|
@@ -12,6 +13,15 @@ class Interscript::Node::Rule::Funcall < Interscript::Node::Rule
|
|
12
13
|
}
|
13
14
|
end
|
14
15
|
|
16
|
+
def reverse
|
17
|
+
self.class.new(Interscript::Stdlib.reverse_function[@name.to_sym],
|
18
|
+
reverse_run: reverse_run.nil? ? nil : !reverse_run, **kwargs)
|
19
|
+
end
|
20
|
+
|
21
|
+
def ==
|
22
|
+
super && self.name == other.name && self.kwargs == other.kwargs
|
23
|
+
end
|
24
|
+
|
15
25
|
def inspect
|
16
26
|
"#{@name} #{kwargs.inspect[1..-2]}"
|
17
27
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
class Interscript::Node::Rule::Run < Interscript::Node::Rule
|
2
|
-
attr_accessor :stage
|
3
|
-
def initialize stage
|
2
|
+
attr_accessor :stage, :reverse_run
|
3
|
+
def initialize stage, reverse_run: nil
|
4
4
|
@stage = stage
|
5
|
+
@reverse_run = reverse_run
|
5
6
|
end
|
6
7
|
|
7
8
|
def to_hash
|
@@ -9,7 +10,19 @@ class Interscript::Node::Rule::Run < Interscript::Node::Rule
|
|
9
10
|
:stage => self.stage.to_hash }
|
10
11
|
end
|
11
12
|
|
13
|
+
def reverse
|
14
|
+
Interscript::Node::Rule::Run.new(stage,
|
15
|
+
reverse_run: reverse_run.nil? ? nil : !reverse_run
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def ==(other)
|
20
|
+
super && self.stage == other.stage
|
21
|
+
end
|
22
|
+
|
12
23
|
def inspect
|
13
|
-
"run #{@stage.inspect}"
|
24
|
+
out = "run #{@stage.inspect}"
|
25
|
+
out += ", reverse_run: #{@reverse_run.inspect}" unless reverse_run.nil?
|
26
|
+
out
|
14
27
|
end
|
15
28
|
end
|
@@ -1,12 +1,19 @@
|
|
1
1
|
class Interscript::Node::Rule::Sub < Interscript::Node::Rule
|
2
2
|
attr_accessor :from, :to
|
3
3
|
attr_accessor :before, :not_before, :after, :not_after
|
4
|
+
attr_accessor :reverse_before, :reverse_not_before, :reverse_after, :reverse_not_after
|
5
|
+
attr_accessor :reverse_run
|
4
6
|
attr_accessor :priority
|
5
7
|
|
6
|
-
def initialize from, to,
|
8
|
+
def initialize (from, to,
|
9
|
+
before: nil, not_before: nil,
|
10
|
+
after: nil, not_after: nil,
|
11
|
+
priority: nil, reverse_run: nil)
|
7
12
|
self.from = Interscript::Node::Item.try_convert from
|
8
13
|
if to == :upcase
|
9
14
|
self.to = :upcase
|
15
|
+
elsif to == :downcase
|
16
|
+
self.to = :downcase
|
10
17
|
else
|
11
18
|
self.to = Interscript::Node::Item.try_convert to
|
12
19
|
end
|
@@ -16,6 +23,8 @@ class Interscript::Node::Rule::Sub < Interscript::Node::Rule
|
|
16
23
|
#raise TypeError, "Can't supply both before and not_before" if before && not_before
|
17
24
|
#raise TypeError, "Can't supply both after and not_after" if after && not_after
|
18
25
|
|
26
|
+
self.reverse_run = reverse_run
|
27
|
+
|
19
28
|
self.before = Interscript::Node::Item.try_convert(before) if before
|
20
29
|
self.after = Interscript::Node::Item.try_convert(after) if after
|
21
30
|
self.not_before = Interscript::Node::Item.try_convert(not_before) if not_before
|
@@ -37,7 +46,13 @@ class Interscript::Node::Rule::Sub < Interscript::Node::Rule
|
|
37
46
|
puts params.inspect if $DEBUG
|
38
47
|
hash = { :class => self.class.to_s,
|
39
48
|
:from => self.from.to_hash,
|
40
|
-
:to => Symbol === self.to ? self.to : self.to.to_hash
|
49
|
+
:to => Symbol === self.to ? self.to : self.to.to_hash,
|
50
|
+
:reverse_run => self.reverse_run,
|
51
|
+
:before => self.before&.to_hash,
|
52
|
+
:not_before => self.not_before&.to_hash,
|
53
|
+
:after => self.after&.to_hash,
|
54
|
+
:not_after => self.not_after&.to_hash,
|
55
|
+
:priority => self.priority
|
41
56
|
}
|
42
57
|
|
43
58
|
hash[:before] = self.before&.to_hash if self.before
|
@@ -49,19 +64,165 @@ class Interscript::Node::Rule::Sub < Interscript::Node::Rule
|
|
49
64
|
hash
|
50
65
|
end
|
51
66
|
|
67
|
+
def reverse
|
68
|
+
if to == :upcase
|
69
|
+
xfrom = from.downcase
|
70
|
+
xto = :downcase
|
71
|
+
elsif to == :downcase
|
72
|
+
xfrom = from.upcase
|
73
|
+
xto = :upcase
|
74
|
+
else
|
75
|
+
xto, xfrom = reverse_transfer(from, to)
|
76
|
+
end
|
77
|
+
|
78
|
+
# A special case: sub "a", "" shouldn't be present in a reverse map
|
79
|
+
rrun = self.reverse_run.nil? ? nil : !self.reverse_run
|
80
|
+
if rrun.nil? && !has_assertions? &&
|
81
|
+
(xfrom == "" ||
|
82
|
+
(Interscript::Node::Item::String === xfrom && xfrom.data == '') ||
|
83
|
+
(Interscript::Node::Item::Alias === xfrom && xfrom.name == :none)
|
84
|
+
)
|
85
|
+
|
86
|
+
rrun = true
|
87
|
+
end
|
88
|
+
|
89
|
+
Interscript::Node::Rule::Sub.new(xfrom, xto,
|
90
|
+
before: before, after: after,
|
91
|
+
not_before: not_before, not_after: not_after,
|
92
|
+
|
93
|
+
reverse_run: rrun,
|
94
|
+
|
95
|
+
priority: priority ? -priority : nil
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
def has_assertions?
|
100
|
+
!!(before || not_before || not_after || after)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Attempt to transfer some references to boundary/line_begin around.
|
104
|
+
# Those in general should go into before/after clauses, but for now
|
105
|
+
# let's try to get the best compatibility possible. Also, CaptureGroup,
|
106
|
+
# CaptureRef need to be shifted around
|
107
|
+
def reverse_transfer from, to
|
108
|
+
# This part is about moving initial and final boundary like aliases
|
109
|
+
case from
|
110
|
+
when Interscript::Node::Item::Group
|
111
|
+
first = from.children.first
|
112
|
+
last = from.children.last
|
113
|
+
|
114
|
+
if Interscript::Node::Item::Alias === first && first.boundary_like?
|
115
|
+
out = Interscript::Node::Item::Group.new + first + to
|
116
|
+
to = out.compact
|
117
|
+
|
118
|
+
from = from.dup.tap do |i|
|
119
|
+
i.children = i.children[1..-1]
|
120
|
+
end.compact
|
121
|
+
end
|
122
|
+
|
123
|
+
if Interscript::Node::Item::Alias === last && last.boundary_like?
|
124
|
+
out = Interscript::Node::Item::Group.new + to + last
|
125
|
+
to = out.compact
|
126
|
+
|
127
|
+
from = from.dup.tap do |i|
|
128
|
+
i.children = i.children[0..-2]
|
129
|
+
end.compact
|
130
|
+
end
|
131
|
+
when Interscript::Node::Item::Alias
|
132
|
+
if from.boundary_like?
|
133
|
+
to = if from.name.to_s.end_with? "_end"
|
134
|
+
Interscript::Node::Item::Group.new + to + from
|
135
|
+
else
|
136
|
+
Interscript::Node::Item::Group.new + from + to
|
137
|
+
end
|
138
|
+
from = Interscript::Node::Item::Alias.new(:none)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# This part is about moving backreferences
|
143
|
+
state = {left:[], right:[]}
|
144
|
+
|
145
|
+
from = reverse_transfer_visit(from, :from, state)
|
146
|
+
to = reverse_transfer_visit(to, :to, state)
|
147
|
+
|
148
|
+
[from, to]
|
149
|
+
end
|
150
|
+
|
151
|
+
private def reverse_transfer_visit(node, type, state)
|
152
|
+
node = Interscript::Node::Item.try_convert(node)
|
153
|
+
|
154
|
+
case node
|
155
|
+
when Interscript::Node::Item::Alias
|
156
|
+
if node.name == :kor_maybedash
|
157
|
+
state[:left] << node
|
158
|
+
Interscript::Node::Item::CaptureRef.new(state[:left].length)
|
159
|
+
else
|
160
|
+
node
|
161
|
+
end
|
162
|
+
when Interscript::Node::Item::String
|
163
|
+
node
|
164
|
+
when Interscript::Node::Item::Any
|
165
|
+
if Array === node.value
|
166
|
+
node.dup.tap do |i|
|
167
|
+
i.value = i.value.map { |c| reverse_transfer_visit(c, type, state) }
|
168
|
+
end
|
169
|
+
else
|
170
|
+
node
|
171
|
+
end
|
172
|
+
when Interscript::Node::Item::Group
|
173
|
+
node.dup.tap do |i|
|
174
|
+
i.children = i.children.map { |c| reverse_transfer_visit(c, type, state) }
|
175
|
+
end
|
176
|
+
when Interscript::Node::Item::Repeat
|
177
|
+
node.dup.tap do |i|
|
178
|
+
i.data = reverse_transfer_visit(i.data, type, state)
|
179
|
+
end
|
180
|
+
when Interscript::Node::Item::CaptureRef
|
181
|
+
if type == :from
|
182
|
+
node
|
183
|
+
elsif state[:right][node.id]
|
184
|
+
node
|
185
|
+
else
|
186
|
+
state[:right][node.id] = true
|
187
|
+
state[:left][node.id - 1] or raise "Capture count doesn't match"
|
188
|
+
end
|
189
|
+
when Interscript::Node::Item::CaptureGroup
|
190
|
+
state[:left] << node
|
191
|
+
out = Interscript::Node::Item::CaptureRef.new(state[:left].length)
|
192
|
+
reverse_transfer_visit(node.data, type, state) # Visit but don't care
|
193
|
+
out
|
194
|
+
else
|
195
|
+
raise "Type #{node.class} unhandled!"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def ==(other)
|
200
|
+
super &&
|
201
|
+
self.from == other.from &&
|
202
|
+
self.to == other.to &&
|
203
|
+
self.before == other.before &&
|
204
|
+
self.after == other.after &&
|
205
|
+
self.not_before == other.not_before &&
|
206
|
+
self.not_after == other.not_after &&
|
207
|
+
self.priority == other.priority
|
208
|
+
end
|
209
|
+
|
52
210
|
def inspect
|
53
211
|
out = "sub "
|
54
212
|
params = []
|
55
213
|
params << @from.inspect
|
56
|
-
if @to
|
57
|
-
params <<
|
214
|
+
if Symbol === @to
|
215
|
+
params << @to.to_s
|
58
216
|
else
|
59
217
|
params << @to.inspect
|
60
218
|
end
|
219
|
+
params << "reverse_run: #{@reverse_run.inspect}" unless @reverse_run.nil?
|
220
|
+
|
61
221
|
params << "before: #{@before.inspect}" if @before
|
62
222
|
params << "after: #{@after.inspect}" if @after
|
63
223
|
params << "not_before: #{@not_before.inspect}" if @not_before
|
64
224
|
params << "not_after: #{@not_after.inspect}" if @not_after
|
225
|
+
|
65
226
|
params << "priority: #{@priority.inspect}" if @priority
|
66
227
|
out << params.join(", ")
|
67
228
|
end
|