inform-runtime 1.0.4

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.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +623 -0
  3. data/README.md +185 -0
  4. data/Rakefile +65 -0
  5. data/config/database.yml +37 -0
  6. data/exe/inform.rb +6 -0
  7. data/game/config.yml +5 -0
  8. data/game/example.inf +76 -0
  9. data/game/example.rb +90 -0
  10. data/game/forms/example_form.rb +2 -0
  11. data/game/grammar/game_grammar.inf.rb +11 -0
  12. data/game/languages/english.rb +2 -0
  13. data/game/models/example_model.rb +2 -0
  14. data/game/modules/example_module.rb +9 -0
  15. data/game/rules/example_state.rb +2 -0
  16. data/game/scripts/example_script.rb +2 -0
  17. data/game/topics/example_topic.rb +2 -0
  18. data/game/verbs/game_verbs.rb +15 -0
  19. data/game/verbs/metaverbs.rb +2028 -0
  20. data/lib/runtime/articles.rb +138 -0
  21. data/lib/runtime/builtins.rb +359 -0
  22. data/lib/runtime/color.rb +145 -0
  23. data/lib/runtime/command.rb +470 -0
  24. data/lib/runtime/config.rb +48 -0
  25. data/lib/runtime/context.rb +78 -0
  26. data/lib/runtime/daemon.rb +266 -0
  27. data/lib/runtime/database.rb +500 -0
  28. data/lib/runtime/events.rb +771 -0
  29. data/lib/runtime/experimental/handler_dsl.rb +175 -0
  30. data/lib/runtime/game.rb +74 -0
  31. data/lib/runtime/game_loader.rb +132 -0
  32. data/lib/runtime/grammar_parser.rb +553 -0
  33. data/lib/runtime/helpers.rb +177 -0
  34. data/lib/runtime/history.rb +45 -0
  35. data/lib/runtime/inflector.rb +195 -0
  36. data/lib/runtime/io.rb +174 -0
  37. data/lib/runtime/kernel.rb +450 -0
  38. data/lib/runtime/library.rb +59 -0
  39. data/lib/runtime/library_loader.rb +135 -0
  40. data/lib/runtime/link.rb +158 -0
  41. data/lib/runtime/logging.rb +197 -0
  42. data/lib/runtime/mixins.rb +570 -0
  43. data/lib/runtime/module.rb +202 -0
  44. data/lib/runtime/object.rb +761 -0
  45. data/lib/runtime/options.rb +104 -0
  46. data/lib/runtime/persistence.rb +292 -0
  47. data/lib/runtime/plurals.rb +60 -0
  48. data/lib/runtime/prototype.rb +307 -0
  49. data/lib/runtime/publication.rb +92 -0
  50. data/lib/runtime/runtime.rb +321 -0
  51. data/lib/runtime/session.rb +202 -0
  52. data/lib/runtime/stdlib.rb +604 -0
  53. data/lib/runtime/subscription.rb +47 -0
  54. data/lib/runtime/tag.rb +287 -0
  55. data/lib/runtime/tree.rb +204 -0
  56. data/lib/runtime/version.rb +24 -0
  57. data/lib/runtime/world_tree.rb +69 -0
  58. data/lib/runtime.rb +35 -0
  59. metadata +199 -0
@@ -0,0 +1,287 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # Copyright Nels Nelson 2008-2023 but freely usable (see license)
5
+ #
6
+ # This file is part of the Inform Runtime.
7
+ #
8
+ # The Inform Runtime is free software: you can redistribute it and/or
9
+ # modify it under the terms of the GNU General Public License as published
10
+ # by the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # The Inform Runtime is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with the Inform Runtime. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ # Tag
22
+
23
+ if defined?(Sequel::Migration)
24
+ # The TagSetup class
25
+ class TagSetup < Sequel::Migration
26
+ def up
27
+ # return if table_exists? :tag
28
+ log.debug "#up"
29
+ create_table? :tag do
30
+ primary_key :id
31
+ index :name
32
+ index :created_at
33
+
34
+ String :name, unique: true, null: false
35
+ DateTime :created_at
36
+ DateTime :modified_at
37
+ end
38
+ end
39
+
40
+ def down
41
+ drop_table(:tag, cascade: true) if table_exists? :tag
42
+ end
43
+ end
44
+ # class TagSetup
45
+ end
46
+ # defined?(Sequel::Migration)
47
+
48
+ # The Inform module
49
+ module Inform
50
+ # The Inform::Tag class
51
+ class Tag < Sequel::Model
52
+ set_primary_key :id
53
+ def_column_accessor :created_at, :modified_at
54
+ def_column_accessor :name
55
+
56
+ def before_create
57
+ self.created_at ||= Time.now
58
+ super
59
+ end
60
+
61
+ def after_create
62
+ super
63
+ Inform.attributes.reset
64
+ end
65
+
66
+ def after_save
67
+ super
68
+ self.modified_at = Time.now.utc
69
+ end
70
+
71
+ def to_s
72
+ name
73
+ end
74
+ alias to_str to_s
75
+
76
+ def <=>(other)
77
+ self.name <=> other.name
78
+ end
79
+
80
+ def self.tidy
81
+ db << %(delete from tag where id in
82
+ (select a.id from tag a group by a.id, a.name
83
+ having ((select count(b.id) from tagged b
84
+ where b.tag_id = a.id) = 0)))
85
+ Inform.attributes.reset
86
+ return nil
87
+ end
88
+
89
+ # rubocop: disable Style/FormatStringToken
90
+ def self.dirty
91
+ results = db.fetch %(select a.id, a.name from tag a group by a.id, a.name having
92
+ ((select count(b.id) from tagged b where b.tag_id = a.id) = 0))
93
+ return nil if results.empty?
94
+ s = [format('%5s %20s', *results.first.keys)]
95
+ s.concat(results.collect { |row| format('%5d %20s', *row.values) })
96
+ s.join("\n")
97
+ end
98
+ # rubocop: enable Style/FormatStringToken
99
+
100
+ # rubocop: disable Style/FormatStringToken
101
+ def self.stats
102
+ results = db.fetch %(select a.*, count(a.id) as "number tagged"
103
+ from tag a, tagged b where b.tag_id = a.id group by a.id, a.name)
104
+ return nil if results.empty?
105
+ s = [format('%5s %20s %15s', *results.first.keys)]
106
+ s.concat(results.collect { |row| format('%5d %20s %15s', *row.values) })
107
+ s.join("\n")
108
+ end
109
+ # rubocop: enable Style/FormatStringToken
110
+ end
111
+ end
112
+ # module Inform
113
+
114
+ # The Inform module
115
+ module Inform
116
+ # The TagRegistry class
117
+ class TagRegistry < Set
118
+ SINGLETON = Struct.new(:memo).new
119
+
120
+ def initialize
121
+ super
122
+ init
123
+ end
124
+
125
+ def all_persisted_tags
126
+ return [] unless Inform::Tag.respond_to?(:map)
127
+ Inform::Tag.map { |a| a.name.to_sym }
128
+ rescue Sequel::DatabaseError => e
129
+ log.warn e.message
130
+ return []
131
+ end
132
+
133
+ def init
134
+ self.clear
135
+ self.merge(Inform::Library::DeclaredAttributes.memo)
136
+ self.merge(all_persisted_tags)
137
+ self
138
+ end
139
+ alias reset init
140
+ end
141
+
142
+ def self.attributes
143
+ TagRegistry::SINGLETON.memo ||= TagRegistry.new
144
+ end
145
+ end
146
+
147
+ # Tagged
148
+
149
+ if defined?(Sequel::Migration)
150
+ # The TaggedSetup class
151
+ class TaggedSetup < Sequel::Migration
152
+ def up
153
+ log.debug "#up"
154
+ create_table? :tagged do
155
+ primary_key :id
156
+ foreign_key :object_id, :object, on_delete: :cascade
157
+ foreign_key :tag_id, :tag, on_delete: :cascade
158
+ end
159
+ end
160
+
161
+ def down
162
+ drop_table(:tagged, cascade: true) if table_exists? :tagged
163
+ end
164
+ end
165
+ # class TaggedSetup
166
+ end
167
+ # defined?(Sequel::Migration)
168
+
169
+ # The Inform module
170
+ module Inform
171
+ # The Inform::Tagged class
172
+ class Tagged < Sequel::Model
173
+ set_primary_key :id
174
+ end
175
+ end
176
+ # module Inform
177
+
178
+ # Taggable
179
+
180
+ # The Inform module
181
+ module Inform
182
+ # The Inform::TagHelpers module
183
+ module TagHelpers
184
+ def attributes; tags; end
185
+ def has(*args); tag(*args); end
186
+ def hasnt(*args); untag(*args); end
187
+ def has?(*args); tagged_with_all?(*args); end
188
+ def hasany?(*args); tagged_with_any?(*args); end
189
+ def hasnt?(*args); tagged_with_none?(*args); end
190
+ alias has! hasnt
191
+ end
192
+ end
193
+
194
+ # The Inform module
195
+ module Inform
196
+ # The Inform::Taggable module
197
+ module Taggable
198
+ include TagHelpers
199
+
200
+ def tag(*args)
201
+ # TODO: Generalize workflag to system flags
202
+ workflags.add(self.identity) if args.delete(:workflag)
203
+ a = self.tag_names args
204
+ (a - (self.nil_safe_tags & a)).each do |tag|
205
+ add_tag(Inform::Tag.find_or_create(name: tag.to_s))
206
+ end
207
+ self.save_changes if self.respond_to?(:save_changes)
208
+ end
209
+
210
+ def untag(*args)
211
+ # TODO: Generalize workflag to system flags
212
+ workflags.delete(self.identity) if args.delete(:workflag)
213
+ (self.nil_safe_tags & tag_names(args)).each do |tag|
214
+ remove_tag Inform::Tag.find(name: tag.to_s)
215
+ end
216
+ self.save_changes if self.respond_to?(:save_changes)
217
+ end
218
+ alias tag! untag
219
+
220
+ def tagged_with?(tag)
221
+ tagged_with_any? tag
222
+ end
223
+
224
+ def tagged_with_all?(*args)
225
+ # TODO: Generalize workflag to system flags
226
+ return workflags.include?(self.identity) if args.delete(:workflag)
227
+ a = self.tag_names(args)
228
+ (self.nil_safe_tags & a).length == a.length
229
+ end
230
+
231
+ def tagged_with_any?(*args)
232
+ # TODO: Generalize workflag to system flags
233
+ (args.delete(:workflag) && workflags.include?(self.identity)) || !self.tagged_with_none?(*tag_names(args))
234
+ end
235
+
236
+ def tagged_with_none?(*args)
237
+ # TODO: Generalize workflag to system flags
238
+ # puts "workflags: #{workflags}" if args.include?(:workflag)
239
+ return false if args.delete(:workflag) && workflags.include?(self.identity)
240
+ (nil_safe_tags & tag_names(args)).empty?
241
+ end
242
+
243
+ def tag_names(a)
244
+ a.flatten.map(&:to_s).map(&:intern)
245
+ end
246
+
247
+ def nil_safe_tags
248
+ attempt_twice do
249
+ log.warn "The tags for #{self} is nil" if self.tags.nil?
250
+ # TODO: FIXME
251
+ # Perhaps try adding a semaphore lock here around tags
252
+ self.tags.compact.map(&:to_s).map(&:intern)
253
+ end || Array::Empty
254
+ end
255
+ end
256
+ # module Taggable
257
+ end
258
+ # module Inform
259
+
260
+ # The Inform module
261
+ module Inform
262
+ # The Inform::System module
263
+ module System
264
+ # The Inform::System::Object class
265
+ class Object
266
+ def tag(*args)
267
+ workflags.add self.identity if args.delete :workflag
268
+ tag_names(args).each do |tag|
269
+ tags << tag.to_sym
270
+ end
271
+ self
272
+ end
273
+
274
+ def untag(*args)
275
+ workflags.delete self.identity if args.delete :workflag
276
+ (nil_safe_tags & tag_names(args)).each do |tag|
277
+ tags.delete tag
278
+ end
279
+ self
280
+ end
281
+
282
+ def tags
283
+ @tags ||= []
284
+ end
285
+ end
286
+ end
287
+ end
@@ -0,0 +1,204 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # Copyright Nels Nelson 2008-2023 but freely usable (see license)
5
+ #
6
+ # This file is part of the Inform Runtime.
7
+ #
8
+ # The Inform Runtime is free software: you can redistribute it and/or
9
+ # modify it under the terms of the GNU General Public License as published
10
+ # by the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # The Inform Runtime is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with the Inform Runtime. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ # Tree
22
+
23
+ # The Inform module
24
+ module Inform
25
+ # The Genealogical module
26
+ module Genealogical
27
+ def >(other)
28
+ self << other
29
+ end
30
+
31
+ # TODO: Refactor all of these to use Ruby Sequel dataset methods.
32
+
33
+ def include?(other)
34
+ other.refresh if other.respond_to?(:refresh)
35
+ return true if other.parent == self
36
+ self.children.include?(other)
37
+ end
38
+
39
+ def in?(*others)
40
+ return false unless self.respond_to?(:parent)
41
+ self.refresh if self.respond_to?(:refresh)
42
+ x = self.parent
43
+ x.refresh if x.respond_to?(:refresh)
44
+ return others.include?(x) if others.length > 1
45
+ y = others.first
46
+ return true if self.parent == y
47
+ return false unless y.respond_to?(:include?)
48
+ y.include?(self)
49
+ end
50
+
51
+ def within?(*others)
52
+ x = self
53
+ x.refresh if x.respond_to?(:refresh)
54
+ loop do
55
+ x = x.parent
56
+ break if x.nil?
57
+ return true if others.include?(x)
58
+ x.refresh if x.respond_to?(:refresh)
59
+ end
60
+ false
61
+ end
62
+
63
+ def notin?(*others)
64
+ !self.in?(*others)
65
+ end
66
+
67
+ def branch
68
+ [self] + self.descendants
69
+ end
70
+
71
+ def all?(*args, &block)
72
+ self.children.all?(*args, &block)
73
+ end
74
+
75
+ def any?(*args, &block)
76
+ self.children.any?(*args, &block)
77
+ end
78
+
79
+ def each(*args, &block)
80
+ self.children.each(*args, &block)
81
+ end
82
+
83
+ def each_with_object(*args, &block)
84
+ self.children.each_with_object(*args, &block)
85
+ end
86
+
87
+ def select(*args, &block)
88
+ self.children.select(*args, &block).to_a
89
+ end
90
+
91
+ def collect(*args, &block)
92
+ self.children.collect(*args, &block)
93
+ end
94
+
95
+ def reject(*args, &block)
96
+ self.children.reject(*args, &block)
97
+ end
98
+
99
+ def delete_if(*args, &block)
100
+ self.children.delete_if(*args, &block)
101
+ end
102
+
103
+ def count(*args, &block)
104
+ self.children.count(*args, &block)
105
+ end
106
+
107
+ def map(*args, &block)
108
+ self.children.map(*args, &block)
109
+ end
110
+
111
+ def find(*args, &block)
112
+ self.children.find(*args, &block)
113
+ end
114
+
115
+ def find_all(*args, &block)
116
+ self.children.find_all(*args, &block)
117
+ end
118
+
119
+ def concat(*args, &block)
120
+ self.children.concat(*args, &block)
121
+ end
122
+
123
+ def having(method)
124
+ self.children.having(method)
125
+ end
126
+
127
+ # rubocop: disable Metrics/AbcSize
128
+ def children(o = nil, prop = :@children)
129
+ # TODO: Remove
130
+ unless o.nil?
131
+ log.warn "In genealogical.children(#{o})"
132
+ log.warn " #{o}.respond_to? :children_dataset #=> #{o.respond_to? :children_dataset}"
133
+ log.warn " #{o}.instance_variable_defined?(#{prop}) #=> #{o.respond_to? :children_dataset}"
134
+ end
135
+ self.safe_refresh if self.respond_to?(:safe_refresh)
136
+ o.safe_refresh if o.respond_to?(:safe_refresh)
137
+ return children.length if o.respond_to? :children_dataset
138
+ return o.instance_variable_get(prop).length if o.instance_variable_defined?(prop)
139
+ super()
140
+ end
141
+ # rubocop: enable Metrics/AbcSize
142
+
143
+ # rubocop: disable Metrics/AbcSize
144
+ # rubocop: disable Metrics/CyclomaticComplexity
145
+ # rubocop: disable Metrics/MethodLength
146
+ # rubocop: disable Metrics/PerceivedComplexity
147
+ def child(o = self, prop = :@children)
148
+ if o.instance_variable_defined?(prop)
149
+ # The idea here is that o may be an Inform::System::Object.
150
+ children = o.instance_variable_get(prop)
151
+ return nil unless children.respond_to?(:first)
152
+ children.first
153
+ elsif o.respond_to?(:children_dataset)
154
+ # It may be necessary to find some way of caching
155
+ # the parent-children relationship. Therefore,
156
+ # the following benchmarking is a way to gather
157
+ # data so that it might be determined whether
158
+ # enabling caching makes any difference in
159
+ # execution speed.
160
+ begin
161
+ # TODO: Remove:
162
+ if defined?(DEBUG) && @parser_trace >= 12
163
+ log.debug "#{indent}#{self}.children_dataset execution -- BEGIN"
164
+ end
165
+ # TODO: Remove:
166
+ start = Time.now
167
+ return o.children_dataset.first
168
+ ensure # TODO: Remove
169
+ # TODO: Remove
170
+ elapsed = Time.now - start if defined? DEBUG
171
+ # TODO: Remove:
172
+ if defined?(DEBUG) && @parser_trace >= 12
173
+ log.debug "#{indent}#{self}.children_dataset executed in #{elapsed.round(6)} milliseconds"
174
+ end
175
+ end
176
+ else
177
+ log.warn "Object #{o} <#{o.identity}> (#{o.class}) has no children accessor"
178
+ nil
179
+ end
180
+ end
181
+ # rubocop: enable Metrics/AbcSize
182
+ # rubocop: enable Metrics/CyclomaticComplexity
183
+ # rubocop: enable Metrics/MethodLength
184
+ # rubocop: enable Metrics/PerceivedComplexity
185
+
186
+ def sibling(o = self)
187
+ o.refresh if o.respond_to? :refresh
188
+ return nil if o.parent.nil?
189
+ parent = o.parent
190
+ return nil unless parent.respond_to?(:children)
191
+ children = o.parent.children
192
+ return nil if children.nil? || children.empty?
193
+ children[children.index(o) + 1]
194
+ end
195
+
196
+ def siblings(orphanage = false)
197
+ if self.parent.nil?
198
+ return orphanage ? Inform::Object.roots : []
199
+ end
200
+ self.refresh if self.respond_to? :refresh
201
+ self.parent.children - [self]
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # Copyright Nels Nelson 2008-2023 but freely usable (see license)
5
+ #
6
+ # This file is part of the Inform Runtime.
7
+ #
8
+ # The Inform Runtime is free software: you can redistribute it and/or
9
+ # modify it under the terms of the GNU General Public License as published
10
+ # by the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # The Inform Runtime is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with the Inform Runtime. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ module Inform
22
+ VERSION = '1.0.4'.freeze
23
+ VN_1610 = '1610'.freeze
24
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # Copyright Nels Nelson 2008-2023 but freely usable (see license)
5
+ #
6
+ # This file is part of the Inform Runtime.
7
+ #
8
+ # The Inform Runtime is free software: you can redistribute it and/or
9
+ # modify it under the terms of the GNU General Public License as published
10
+ # by the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # The Inform Runtime is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with the Inform Runtime. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ require_relative 'object'
22
+ require_relative 'link'
23
+ require_relative 'tag'
24
+ require_relative 'module'
25
+ require_relative 'tree'
26
+ require_relative 'daemon'
27
+
28
+ # The Inform module to include additional
29
+ # modules with Inform::Object, Inform::System::Object,
30
+ # and Inform::Event
31
+ module Inform
32
+ # The Inform::Object functionality
33
+ class Object
34
+ include Inform
35
+ include Inform::IO if defined?(Inform::IO)
36
+ include Inform::Events if defined?(Inform::Events)
37
+ include Inform::Publisher if defined?(Inform::Publisher)
38
+ include Inform::Prototypical if defined?(Inform::Prototypical)
39
+ include Inform::Linkable
40
+ include Inform::Taggable
41
+ include Inform::Modular
42
+ include Inform::Genealogical
43
+ include Inform::Daemons
44
+ end
45
+
46
+ # The Inform::Event class
47
+ class Event
48
+ include Inform::Publisher
49
+ end
50
+
51
+ # The Inform::System module to be used as
52
+ # a namespace differentiator from the Inform::Object
53
+ module System
54
+ # The Inform::System::Object functionality
55
+ class Object
56
+ include Inform
57
+ include Inform::IO if defined?(Inform::IO)
58
+ include Inform::Events if defined?(Inform::Events)
59
+ include Inform::Publisher if defined?(Inform::Publisher)
60
+ # TODO: I don't think there is any legitimate reason for
61
+ # System::Object instances to have prototypical functionality.
62
+ include Inform::Prototypical if defined?(Inform::Prototypical)
63
+ include Inform::Linkable
64
+ include Inform::Taggable
65
+ include Inform::Genealogical
66
+ include Inform::Daemons
67
+ end
68
+ end
69
+ end
data/lib/runtime.rb ADDED
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # Copyright Nels Nelson 2008-2023 but freely usable (see license)
5
+ #
6
+ # This file is part of the Inform Runtime.
7
+ #
8
+ # The Inform Runtime is free software: you can redistribute it and/or
9
+ # modify it under the terms of the GNU General Public License as published
10
+ # by the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # The Inform Runtime is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with the Inform Runtime. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ require_relative 'runtime/builtins'
22
+ require_relative 'runtime/stdlib'
23
+ require_relative 'runtime/logging'
24
+ require_relative 'runtime/prototype'
25
+ require_relative 'runtime/command'
26
+ require_relative 'runtime/runtime'
27
+ require_relative 'runtime/persistence'
28
+ require_relative 'runtime/history'
29
+ require_relative 'runtime/events'
30
+ require_relative 'runtime/grammar_parser'
31
+ require_relative 'runtime/kernel'
32
+ require_relative 'runtime/mixins'
33
+ require_relative 'runtime/helpers'
34
+ require_relative 'runtime/io'
35
+ require_relative 'runtime/publication'