story-gen 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
data/NEWS CHANGED
@@ -1,3 +1,7 @@
1
+ 0.1.8
2
+ Add "when" keyword
3
+ Use FFaker
4
+
1
5
  0.1.7
2
6
  Bug fixes, extract Parse into separate gem
3
7
 
@@ -23,4 +27,4 @@
23
27
  Alternate form of compound statement (with "-") is removed
24
28
 
25
29
  0.0.4:
26
- Like, first release
30
+ Like, first release
data/README.md CHANGED
@@ -249,6 +249,23 @@ There are other statements you can use:
249
249
 
250
250
  A random <statement> is chosen and executed.
251
251
 
252
+ - "When":
253
+
254
+ <pre><code>
255
+ When &lt;fact&gt; &lt;statement&gt;
256
+ </code></pre>
257
+
258
+ When you try to state the &lt;fact&gt; then &lt;statement&gt; is executed.
259
+
260
+ <pre><code>
261
+ When X loves Y:
262
+ ""X" marries "Y"!";
263
+ .
264
+ "John" loves "Liza";
265
+ </code></pre>
266
+
267
+ The code above prints "John marries Liza!"
268
+
252
269
  ### Notes ###
253
270
 
254
271
  `(note: ...)` comment may have nested parentheses:
@@ -1,237 +1,26 @@
1
1
  # encoding: UTF-8
2
+ require 'ffaker'
2
3
 
3
4
  class Names
4
5
 
5
6
  # @return [Array<String>]
6
7
  def self.russian_male
7
- %W{
8
- Адам
9
- Адриан
10
- Александр
11
- Алексей
12
- Анатолий
13
- Андрей
14
- Антон
15
- Аркадий
16
- Арсений
17
- Артем
18
- Артур
19
-
20
- Богдан
21
- Борис
22
-
23
- Вадим
24
- Валентин
25
- Валерий
26
- Василий
27
- Виктор
28
- Виталий
29
- Владимир
30
- Владислав
31
- Вячеслав
32
-
33
- Геннадий
34
- Георгий
35
- Герман
36
- Глеб
37
- Григорий
38
-
39
- Давид
40
- Даниил
41
- Денис
42
- Дмитрий
43
-
44
- Евгений
45
- Егор
46
- Ефим
47
-
48
- Захар
49
-
50
- Иван
51
- Игорь
52
- Илья
53
-
54
- Кирилл
55
- Константин
56
-
57
- Лев
58
- Леонид
59
-
60
- Максим
61
- Марк
62
- Матвей
63
- Мирослав
64
- Михаил
65
-
66
- Назар
67
- Нестор
68
- Никита
69
- Николай
70
-
71
- Олег
72
- Орест
73
- Оскар
74
- Остап
75
-
76
- Павел
77
- Петр
78
- Платон
79
-
80
- Ренат
81
- Родион
82
- Роман
83
- Ростислав
84
- Руслан
85
-
86
- Святослав
87
- Семен
88
- Сергей
89
- Станислав
90
- Степан
91
-
92
- Тарас
93
- Тимофей
94
- Тимур
95
-
96
- Федор
97
- Филипп
98
-
99
- Эдуард
100
-
101
- Юрий
102
-
103
- Яков
104
- Ян
105
- Ярослав
106
- }
8
+ FFaker::NameRU::FIRST_NAMES[:male]
107
9
  end
108
10
 
109
11
  # @return [Array<String>]
110
12
  def self.russian_female
111
- %W{
112
- Агата
113
- Ада
114
- Адель
115
- Адриана
116
- Алевтина
117
- Александра
118
- Алина
119
- Алиса
120
- Алла
121
- Альбина
122
- Анастасия
123
- Ангелина
124
- Анжела
125
- Анна
126
- Антонина
127
- Анфиса
128
- Арина
129
-
130
- Богдана
131
- Борислава
132
-
133
- Валентина
134
- Валерия
135
- Варвара
136
- Василиса
137
- Вера
138
- Вероника
139
- Виктория
140
- Виолетта
141
-
142
- Галина
143
-
144
- Дарья
145
- Диана
146
-
147
- Ева
148
- Евгения
149
- Екатерина
150
- Елена
151
- Елизавета
152
-
153
- Жанна
154
-
155
- Зинаида
156
- Зоя
157
-
158
- Илона
159
- Инга
160
- Инесса
161
- Инна
162
- Ирина
163
-
164
- Карина
165
- Кира
166
- Клавдия
167
- Клара
168
- Кристина
169
- Ксения
170
-
171
- Лариса
172
- Лидия
173
- Лилия
174
- Любовь
175
- Людмила
176
-
177
- Майя
178
- Маргарита
179
- Марина
180
- Мария
181
- Марта
182
- Марьяна
183
- Мирослава
184
-
185
- Надежда
186
- Наталья
187
- Нелли
188
- Нина
189
-
190
- Оксана
191
- Ольга
192
-
193
- Полина
194
-
195
- Раиса
196
- Регина
197
- Римма
198
- Роза
199
- Роксана
200
- Руслана
201
-
202
- Светлана
203
- Снежана
204
- София
205
-
206
- Таисия
207
- Тамара
208
- Татьяна
209
-
210
- Ульяна
211
-
212
- Христина
213
-
214
- Эвелина
215
- Элеонора
216
- Эльвира
217
- Эмма
218
-
219
- Юлиана
220
- Юлия
221
-
222
- Яна
223
- Ярослава
224
- }
13
+ FFaker::NameRU::FIRST_NAMES[:female]
225
14
  end
226
15
 
227
16
  # @return [Array<String>]
228
17
  def self.english_male
229
- ["Jack", "Thomas", "Joshua", "Oliver", "Harry", "James", "Charlie", "William", "Daniel", "Samuel", "Alfie", "Benjamin", "Joseph", "George", "Callum", "Jake", "Ethan", "Lewis", "Luke", "Mohammed", "Matthew", "Dylan", "Jacob", "Alexander", "Ryan", "Adam", "Tyler", "Harvey", "Liam", "Max", "Cameron", "Harrison", "Jamie", "Jayden", "Leo", "Owen", "Henry", "Connor", "Archie", "Nathan", "Ben", "Muhammad", "Oscar", "Edward", "Lucas", "Michael", "Isaac", "Aaron", "Kyle", "Noah", "Finley", "Rhys", "Bradley", "Charles", "Toby", "Louis", "Brandon", "Logan", "Mason", "Reece", "Kieran", "Alex", "Riley", "Finlay", "Kai", "Freddie", "David", "Harley", "Kian", "Mohammad", "Bailey", "Sam", "Luca", "Joel", "Theo", "Leon", "John", "Robert", "Ashton", "Ellis", "Joe", "Aidan", "Billy", "Corey", "Hayden", "Evan", "Zachary", "Taylor", "Christopher", "Sebastian", "Elliot", "Morgan", "Jay", "Dominic", "Reuben", "Gabriel", "Sean", "Louie", "Andrew", "Frederick", "Ewan", "Zak"]
18
+ FFaker::Name::FIRST_NAMES_MALE
230
19
  end
231
20
 
232
21
  # @return [Array<String>]
233
22
  def self.english_female
234
- ["Olivia", "Grace", "Ruby", "Jessica", "Emily", "Sophie", "Chloe", "Lucy", "Lily", "Ella", "Ellie", "Amelia", "Charlotte", "Katie", "Mia", "Hannah", "Evie", "Megan", "Amy", "Isabella", "Millie", "Isabelle", "Abigail", "Freya", "Molly", "Daisy", "Holly", "Emma", "Erin", "Poppy", "Jasmine", "Phoebe", "Leah", "Keira", "Caitlin", "Imogen", "Madison", "Rebecca", "Elizabeth", "Georgia", "Sophia", "Lauren", "Scarlett", "Amber", "Ava", "Eleanor", "Bethany", "Alice", "Isabel", "Summer", "Paige", "Anna", "Lola", "Libby", "Eva", "Maisie", "Isobel", "Brooke", "Lilly", "Alisha", "Tia", "Sarah", "Amelie", "Gracie", "Faith", "Rosie", "Courtney", "Matilda", "Niamh", "Maddison", "Sienna", "Eve", "Aimee", "Skye", "Zara", "Isla", "Shannon", "Madeleine", "Harriet", "Zoe", "Nicole", "Sofia", "Abbie", "Maya", "Lacey", "Rachel", "Francesca", "Layla", "Lydia", "Alicia", "Hollie", "Martha", "Alexandra", "Julia", "Natasha", "Lexie", "Mollie", "Morgan", "Maria", "Demi", "Rose", "Laura", "Lara", "Victoria", "Tilly", "Sara", "Evelyn", "Eloise"]
23
+ FFaker::Name::FIRST_NAMES_FEMALE
235
24
  end
236
25
 
237
- end
26
+ end
@@ -28,26 +28,31 @@ class Story
28
28
  #
29
29
  c = Parse.new.(text, file).to_code
30
30
  #
31
- relation_id_to_var_arg_valuesss_var = Hash.new do |h, relation_id|
32
- h[relation_id] = "@#{INTERNAL_VAR_PREFIX}var_arg_valuesss#{h.size}"
31
+ relation_id_to_var_id = Hash.new { |h, relation_id| h[relation_id] = h.size }
32
+ relation_ids = lambda { relation_id_to_var_id.keys }
33
+ relation_id_to_var_arg_valuesss_var = lambda do |relation_id|
34
+ "@#{INTERNAL_VAR_PREFIX}var_arg_valuesss#{relation_id_to_var_id[relation_id]}"
35
+ end
36
+ relation_id_to_trigger_var = lambda do |relation_id|
37
+ "@#{INTERNAL_VAR_PREFIX}trigger#{relation_id_to_var_id[relation_id]}"
33
38
  end
34
39
  #
35
40
  c = c.map_non_code_parts do |part|
36
- if part.is_a? VarArgValuesssVar
37
- relation_id_to_var_arg_valuesss_var[part.relation_id]
38
- else
39
- raise "unknown non-code part type: #{part.inspect}"
41
+ case part
42
+ when VarArgValuesssVar then relation_id_to_var_arg_valuesss_var[part.relation_id]
43
+ when TriggerVar then relation_id_to_trigger_var[part.relation_id]
44
+ else raise "unknown non-code part type: #{part.inspect}"
40
45
  end
41
46
  end
42
47
  #
43
- relation_ids_code = relation_id_to_var_arg_valuesss_var.keys.
48
+ relation_ids_code = relation_ids.().
44
49
  map { |relation_id| relation_id.join(" ") }.
45
50
  sort.
46
51
  to_rb
47
52
  #
48
- init_var_arg_valuesss_vars = relation_id_to_var_arg_valuesss_var.
49
- map do |relation_id, var|
50
- "#{var} = Set.new # #{relation_id}\n"
53
+ init_var_arg_valuesss_vars = relation_ids.().
54
+ map do |relation_id|
55
+ "#{relation_id_to_var_arg_valuesss_var[relation_id]} = Set.new # #{relation_id}\n"
51
56
  end.
52
57
  join_code
53
58
  #
@@ -118,6 +123,9 @@ class Story
118
123
  # @!visibility private
119
124
  VarArgValuesssVar = Struct.new :relation_id, :pos
120
125
 
126
+ #@!visibility private
127
+ TriggerVar = Struct.new :relation_id, :pos
128
+
121
129
  Var = ASTNode.new :name, :original_name do
122
130
 
123
131
  alias name_super name
@@ -202,24 +210,24 @@ class Story
202
210
  reject
203
211
  else
204
212
  args = subexpr.args
213
+ args_code = args.zip(0...args.size).
214
+ map do |arg, i|
215
+ case arg
216
+ when Asterisk then raise Parse::Error.new(arg.pos, "not supported")
217
+ when Var then at(arg.pos) { arg.name }
218
+ when Above[Var] then at(arg.pos) { arg.var.name }
219
+ else arg.to_rb
220
+ end
221
+ end.
222
+ join_code(", ")
223
+ trigger_var = non_code(TriggerVar[subexpr.relation_id, pos])
205
224
  code <<
206
- non_code(VarArgValuesssVar[subexpr.relation_id, pos]) <<
207
- ".add([" <<
208
- args.zip(0...args.size).
209
- map do |arg, i|
210
- case arg
211
- when Asterisk then
212
- raise Parse::Error.new(arg.pos, "not supported")
213
- when Var then
214
- at(arg.pos) { arg.name }
215
- when Above[Var] then
216
- at(arg.pos) { arg.var.name }
217
- else
218
- arg.to_rb
219
- end
220
- end.
221
- join_code(", ") <<
222
- "])"
225
+ "(if " << trigger_var << " then " << "\n"<<
226
+ trigger_var << ".call(" << args_code << ")" << "\n"<<
227
+ "else" << "\n" <<
228
+ non_code(VarArgValuesssVar[subexpr.relation_id, pos]) <<
229
+ ".add([" << args_code << "])" << "\n"<<
230
+ "end)"
223
231
  end
224
232
  end
225
233
 
@@ -249,6 +257,34 @@ class Story
249
257
 
250
258
  end
251
259
 
260
+ Statement::When = ASTNode.new :condition, :action do
261
+
262
+ def to_code
263
+ case condition
264
+ when FactExpr::Primary
265
+ args_code = condition.args.
266
+ map do |arg|
267
+ case arg
268
+ when Asterisk then nil
269
+ when Var then arg.name
270
+ when Above[Var] then arg.var.name
271
+ else raise Parse::Error.new(arg.pos, "not supported")
272
+ end
273
+ end.
274
+ compact.
275
+ join_code(", ")
276
+ code << "(" << non_code(TriggerVar[condition.relation_id, pos]) << " = " <<
277
+ "lambda do |" << args_code << "|\n" <<
278
+ action.to_code << "\n" <<
279
+ "end\n" <<
280
+ ")"
281
+ else
282
+ raise Parse::Error.new(condition.pos, "not supported")
283
+ end
284
+ end
285
+
286
+ end
287
+
252
288
  Statement::Compound = ASTNode.new :statements do
253
289
 
254
290
  def to_code
@@ -616,6 +652,7 @@ class Story
616
652
 
617
653
  rule :statement do
618
654
  _{ statement_if } or
655
+ _{ statement_when } or
619
656
  _{ statement_while } or
620
657
  _{ statement_for_all } or
621
658
  _{ statement_n_times } or
@@ -669,6 +706,11 @@ class Story
669
706
  }
670
707
  end
671
708
 
709
+ rule :statement_when do
710
+ _when_ and f = fact_expr_primary and s = statement and
711
+ _(Statement::When[f, s])
712
+ end
713
+
672
714
  rule :statement_while do
673
715
  _while_ and f = fact_expr and s = statement and
674
716
  _(Statement::While[f, s])
@@ -845,6 +887,7 @@ class Story
845
887
  keyword :all, "`all'", /^(all|всех)$/
846
888
  keyword :_while_, "`while'", /^([Ww]hile|[Пп]ока)$/
847
889
  keyword :_if_, "`if'", /^([Ii]f|[Ее]сли)$/
890
+ keyword :_when_, "`when'", /^([Ww]hen|[Кк]огда)$/
848
891
  keyword :_then_, "`then'", /^(then|то)$/
849
892
  keyword :otherwise, "`otherwise'", /^([Oo]therwise|[Ии]наче)$/
850
893
  keyword :_not_, "`not'", /^(not|не)$/
@@ -8,7 +8,6 @@ Fight club
8
8
 
9
9
  ```
10
10
  require 'unique_names'
11
-
12
11
  names = UniqueNames.english_male
13
12
  ```
14
13
 
@@ -33,6 +32,15 @@ names = UniqueNames.english_male
33
32
  nl;
34
33
  .
35
34
 
35
+ When A beats B:
36
+ if:
37
+ - ^A uses "hands" then ""A" has beaten "B". ";
38
+ - ^A uses "feet" then ""A" has kicked "B". ";
39
+ - ^A uses "hooves" then ""A" has kicked "B" and knocked him out. ";
40
+ - ^A uses "claws" then ""A" has scratched the whole "B". ";
41
+ B is not in;
42
+ .
43
+
36
44
  nl
37
45
  "Let the tournament begin!" nl
38
46
  nl
@@ -40,16 +48,7 @@ nl
40
48
  While the tournament not complete:
41
49
  If X is in and Y is in and X != Y then:
42
50
  (note: fight!)
43
- either (X won; Y lost) or (Y won; X lost);
44
- if A won and B lost then:
45
- if:
46
- - ^A uses "hands" then ""A" has beaten "B". ";
47
- - ^A uses "feet" then ""A" has kicked "B". ";
48
- - ^A uses "hooves" then ""A" has kicked "B" and knocked him out. ";
49
- - ^A uses "claws" then ""A" has scratched the whole "B". ";
50
- A not won; B not lost;
51
- B is not in;
52
- .
51
+ either (X beats Y) or (Y beats X);
53
52
  .
54
53
  Otherwise the tournament complete;
55
54
  .
@@ -33,6 +33,15 @@ names = UniqueNames.russian_male
33
33
  nl;
34
34
  .
35
35
 
36
+ Когда A победил B:
37
+ если:
38
+ - ^A использует "руки", то ""A" избил "B". ";
39
+ - ^A использует "ноги", то ""A" запинал "B". ";
40
+ - ^A использует "копыта", то ""A" лягнул "B" и вырубил его. ";
41
+ - ^A использует "когти", то ""A" исцарапал всего "B". ";
42
+ B не участвует в турнире;
43
+ .
44
+
36
45
  nl
37
46
  "Да начнется турнир!" nl
38
47
  nl
@@ -40,19 +49,10 @@ nl
40
49
  Пока не конец турнира:
41
50
  Если X участвует в турнире и Y участвует в турнире и X != Y, то:
42
51
  (note: бой!)
43
- либо (X победил; Y проиграл), либо (Y победил; X проиграл);
44
- если A победил и B проиграл, то:
45
- если:
46
- - ^A использует "руки", то ""A" избил "B". ";
47
- - ^A использует "ноги", то ""A" запинал "B". ";
48
- - ^A использует "копыта", то ""A" лягнул "B" и вырубил его. ";
49
- - ^A использует "когти", то ""A" исцарапал всего "B". ";
50
- A не победил; B не проиграл;
51
- B не участвует в турнире;
52
- .
52
+ либо (X победил Y), либо (Y победил X);
53
53
  .
54
54
  Иначе конец турнира;
55
55
  .
56
56
  Если X участвует в турнире, то ""X" - победитель!"
57
57
  nl
58
- nl
58
+ nl
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: story-gen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-05-27 00:00:00.000000000 Z
12
+ date: 2017-03-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parse-framework
@@ -27,6 +27,22 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: ffaker
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
30
46
  description: Generate stories from descriptions based on Facts!
31
47
  email: various.furriness@gmail.com
32
48
  executables: