Skip to content

Commit d1bf8c5

Browse files
author
webdev778
committed
Interscript.transliterate_each
1 parent 716e606 commit d1bf8c5

File tree

10 files changed

+120
-5
lines changed

10 files changed

+120
-5
lines changed

ruby/lib/interscript.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ def transliterate(system_code, string, maps={}, compiler: Interscript::Interpret
3636
load(system_code, maps, compiler: compiler).(string)
3737
end
3838

39+
# Gives each possible value of the transliteration.
40+
def transliterate_each(system_code, string, maps={}, &block)
41+
load(system_code, maps).(string, each: true, &block)
42+
end
43+
3944
def transliterate_file(system_code, input_file, output_file, maps={})
4045
input = File.read(input_file)
4146
output = transliterate(system_code, input, maps)

ruby/lib/interscript/interpreter.rb

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,68 @@ def compile(map, _:nil)
55
self
66
end
77

8-
def call(str, stage=:main)
8+
def call(str, stage=:main, each: false, &block)
99
stage = @map.stages[stage]
10-
Stage.new(@map, str).execute_rule(stage)
10+
s =
11+
if each
12+
e = Enumerator.new do |yielder|
13+
options = []
14+
options_set = false
15+
choices = nil
16+
17+
i = 0
18+
19+
loop do
20+
result = nil
21+
22+
f = Fiber.new do
23+
$select_nth_string = true
24+
result = Stage.new(@map, str).execute_rule(stage)
25+
$select_nth_string = false
26+
Fiber.yield(:end)
27+
end
28+
29+
iter = 0
30+
31+
loop do
32+
break if f.resume == :end
33+
# hash is unused for now... some problems may arise in certain
34+
# scenarios that are not a danger right now, but i'm genuinely
35+
# unsure how it can be handled.
36+
#
37+
# This scenario is described in a commented out test.
38+
type, value, hash = f.resume
39+
if options_set
40+
f.resume(choices[i][iter])
41+
else
42+
options[iter] = value
43+
f.resume(0)
44+
end
45+
iter += 1
46+
end
47+
48+
unless options_set
49+
options_set = true
50+
51+
opts = options.map { |i| (0...i).to_a }
52+
choices = opts[0].product(*opts[1..-1])
53+
end
54+
55+
yielder.yield(result)
56+
57+
i += 1
58+
break if i == choices.length
59+
end
60+
end
61+
62+
if block_given?
63+
e.each(&block)
64+
else
65+
e
66+
end
67+
else
68+
Stage.new(@map, str).execute_rule(stage)
69+
end
1170
end
1271

1372
class Stage
@@ -106,7 +165,7 @@ def build_regexp(r)
106165
end
107166

108167
def build_item i, target=nil, doc=@map
109-
i = i.first_string if %i[str parstr].include? target
168+
i = i.nth_string if %i[str parstr].include? target
110169
i = Interscript::Node::Item.try_convert(i)
111170
target = :par if target == :parstr
112171

ruby/lib/interscript/node/item/alias.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ def first_string
2323
self
2424
end
2525

26+
alias nth_string first_string
27+
2628
def to_hash
2729
{ :class => self.class.to_s,
2830
:name => name,

ruby/lib/interscript/node/item/any.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ def first_string
3636
end
3737
end
3838

39+
def nth_string
40+
return first_string unless $select_nth_string
41+
42+
d = data
43+
Fiber.yield(:prepare)
44+
id = Fiber.yield(:select_nth_string, d.count, self.hash)
45+
Fiber.yield(:selection)
46+
Interscript::Node::Item.try_convert(value[id]).nth_string
47+
end
48+
3949
def max_length
4050
self.data.map(&:max_length).max
4151
end

ruby/lib/interscript/node/item/capture.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ def first_string
1111
data.first_string
1212
end
1313

14+
def nth_string
15+
data.nth_string
16+
end
17+
1418
def to_hash
1519
{ :class => self.class.to_s,
1620
:data => self.data.to_hash }
@@ -33,6 +37,8 @@ def first_string
3337
self
3438
end
3539

40+
alias nth_string first_string
41+
3642
def to_hash
3743
{ :class => self.class.to_s,
3844
:id => self.id }

ruby/lib/interscript/node/item/group.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ def first_string
3232
self.children.map(&:first_string).reduce(&:+)
3333
end
3434

35+
def nth_string
36+
self.children.map(&:nth_string).reduce(&:+)
37+
end
38+
3539
def max_length
3640
@children.map { |i| i.max_length }.sum
3741
end

ruby/lib/interscript/node/item/repeat.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ def first_string
99
data.first_string
1010
end
1111

12+
def nth_string
13+
data.nth_string
14+
end
15+
1216
def max_length
1317
data.max_length
1418
end

ruby/lib/interscript/node/item/string.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ def first_string
1717
self.data
1818
end
1919

20+
alias nth_string first_string
21+
2022
def + other
2123
if self.data == ""
2224
Interscript::Node::Item.try_convert(other)

ruby/spec/spec_helper.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ def each_compiler &block
5151
end
5252

5353
class Interscript::Node::Document
54-
def call(str, stage=:main, compiler=$compiler || Interscript::Interpreter)
55-
compiler.(self).(str, stage)
54+
def call(str, stage=:main, compiler=$compiler || Interscript::Interpreter, **kwargs)
55+
compiler.(self).(str, stage, **kwargs)
5656
end
5757
end
5858

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
RSpec.describe "Interscript#transliterate_each" do
2+
before :example do
3+
$compiler = Interscript::Interpreter
4+
end
5+
6+
it "works" do
7+
s = stage {
8+
sub "X", any("abcd")
9+
sub "Y", any("defg")
10+
sub "Z", any("ghij")
11+
}
12+
13+
expect(s.("XYZ", each: true).take(5)).to eq(%w[adg adh adi adj aeg])
14+
end
15+
16+
# it "supports a certain scenario" do
17+
# s = stage {
18+
# sub "X", any(["x", any("abc"), "d"])
19+
# }
20+
#
21+
# expect(s.("X", each: true).to_a).to eq(%w[x x x a b c d d d])
22+
# end
23+
end

0 commit comments

Comments
 (0)