modl 0.3.26 → 0.3.27

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -149
  3. data/Gemfile +4 -2
  4. data/LICENSE.txt +1 -1
  5. data/README.md +19 -11
  6. data/Rakefile +5 -3
  7. data/lib/modl/interpreter.rb +38 -0
  8. data/lib/modl/model/model.rb +264 -0
  9. data/lib/modl/parser/parser.rb +272 -59
  10. data/lib/modl/tokeniser/context.rb +113 -0
  11. data/lib/modl/tokeniser/tokeniser.rb +28 -0
  12. data/lib/modl/util/functions.rb +74 -0
  13. data/lib/modl/util/unicode.rb +44 -0
  14. data/lib/modl/version.rb +5 -0
  15. data/lib/modl.rb +7 -32
  16. data/modl.gemspec +8 -11
  17. metadata +16 -75
  18. data/.DS_Store +0 -0
  19. data/.idea/vcs.xml +0 -6
  20. data/.rspec +0 -3
  21. data/.rubocop.yml +0 -5
  22. data/.travis.yml +0 -7
  23. data/bin/console +0 -14
  24. data/bin/setup +0 -8
  25. data/lib/modl/parser/MODLLexer.interp +0 -132
  26. data/lib/modl/parser/MODLLexer.rb +0 -324
  27. data/lib/modl/parser/MODLLexer.tokens +0 -40
  28. data/lib/modl/parser/MODLParser.interp +0 -93
  29. data/lib/modl/parser/MODLParser.rb +0 -2492
  30. data/lib/modl/parser/MODLParser.tokens +0 -40
  31. data/lib/modl/parser/MODLParserBaseListener.rb +0 -164
  32. data/lib/modl/parser/MODLParserBaseVisitor.rb +0 -107
  33. data/lib/modl/parser/MODLParserListener.rb +0 -151
  34. data/lib/modl/parser/MODLParserVisitor.rb +0 -56
  35. data/lib/modl/parser/class_processor.rb +0 -411
  36. data/lib/modl/parser/evaluator.rb +0 -125
  37. data/lib/modl/parser/file_importer.rb +0 -101
  38. data/lib/modl/parser/global_parse_context.rb +0 -318
  39. data/lib/modl/parser/instruction_processor.rb +0 -82
  40. data/lib/modl/parser/interpreter.rb +0 -75
  41. data/lib/modl/parser/modl_class.rb +0 -138
  42. data/lib/modl/parser/modl_index.rb +0 -54
  43. data/lib/modl/parser/modl_keylist.rb +0 -81
  44. data/lib/modl/parser/modl_method.rb +0 -172
  45. data/lib/modl/parser/object_cache.rb +0 -88
  46. data/lib/modl/parser/orphan_handler.rb +0 -98
  47. data/lib/modl/parser/parsed.rb +0 -1469
  48. data/lib/modl/parser/ref_processor.rb +0 -258
  49. data/lib/modl/parser/substitutions.rb +0 -101
  50. data/lib/modl/parser/sutil.rb +0 -108
  51. data/lib/modl/parser/throwing_error_listener.rb +0 -44
  52. data/lib/modl/parser/unicode_escape_replacer.rb +0 -148
  53. data/lib/modl/parser/unicode_escapes.rb +0 -112
  54. data/lib/modl/parser/version.rb +0 -29
@@ -1,318 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # The MIT License (MIT)
4
- #
5
- # Copyright (c) 2019 NUM Technology Ltd
6
- #
7
- # Permission is hereby granted, free of charge, to any person obtaining a copy
8
- # of this software and associated documentation files (the "Software"), to deal
9
- # in the Software without restriction, including without limitation the rights
10
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
- # copies of the Software, and to permit persons to whom the Software is
12
- # furnished to do so, subject to the following conditions:
13
- #
14
- # The above copyright notice and this permission notice shall be included in
15
- # all copies or substantial portions of the Software.
16
- #
17
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
- # THE SOFTWARE.
24
-
25
- module MODL
26
- module Parser
27
- # Each time we run the parser on a MODL file we need to keep track of a few things so they can be made available
28
- # to other areas of the code. This class is the container for that contextual information, which is gathered
29
- # as the MODL::Parser:Parsed object processes the parse tree.
30
- class GlobalParseContext
31
-
32
- attr_accessor :syntax_version
33
- attr_accessor :max_files_allowed
34
- attr_accessor :structures
35
- attr_reader :interpreter_syntax_version
36
- attr_reader :loaded_files
37
-
38
- def initialize
39
- # This keeps track of all loaded structures from parsed files.
40
- @structures = []
41
- # This is set to true if we encounter a *L[OAD] instruction
42
- @max_files_allowed = 2147483647
43
- # Holds the index array from a MODL file, e.g. '?=a:b:c:d'
44
- @index = []
45
- # Contains all pairs as they are encountered in the parsing process.
46
- @pairs = {}
47
- # Contains all defined and loaded classes for the current MODL document.
48
- @classes_by_id = {}
49
- @classes_by_name = {}
50
- # Hold the user-defined methods.
51
- @methods_hash = {}
52
- @methods_by_id = {}
53
- # Tracks the nesting depth for conditional clauses.
54
- @conditional = 0
55
- # Defaults to 1 and can be overridden by the *version command.
56
- @syntax_version = 1
57
- @interpreter_syntax_version = 1
58
- @loaded_files = []
59
- # Arrays
60
- @arrays_by_id = {}
61
- @arrays_by_name = {}
62
- end
63
-
64
- def loaded_file(str)
65
- @loaded_files << str unless str.nil?
66
- raise InterpreterError, 'Cannot load multiple files after *LOAD instruction' if @loaded_files.length > @max_files_allowed
67
-
68
- end
69
-
70
- def index_value(n, default)
71
- return default if n > @index.length
72
-
73
- @index[n]
74
- end
75
-
76
- def in_condition?
77
- @conditional.positive?
78
- end
79
-
80
- def freeze_max_files(plus)
81
- @max_files_allowed = @loaded_files.length + plus
82
- end
83
-
84
- def enter_condition
85
- @conditional += 1
86
- end
87
-
88
- def exit_condition
89
- @conditional -= 1
90
- end
91
-
92
- def pair(key, val = nil)
93
- return @pairs[key] unless val
94
-
95
- @pairs[key] = val
96
- end
97
-
98
- def classs(key)
99
- if key.is_a? String
100
- result = @classes_by_id[key]
101
- result = @classes_by_name[key] if result.nil?
102
- result
103
- elsif key.is_a? MODLClass
104
- @classes_by_id[key.id] = key if key.id
105
- @classes_by_name[key.name] = key if key.name
106
- end
107
- end
108
-
109
- def arrays(key)
110
- if key.is_a? String
111
- result = @arrays_by_id[key]
112
- result = @arrays_by_name[key] if result.nil?
113
- result
114
- elsif key.is_a? MODLArray
115
- @arrays_by_id[key.id] = key if key.id
116
- @arrays_by_name[key.name] = key if key.name
117
- end
118
- end
119
-
120
- def merge_pairs(other)
121
- @pairs.merge!(other.all_pairs)
122
- end
123
-
124
- def merge_classes(other)
125
- @classes_by_id.merge!(other.all_classes_by_id)
126
- @classes_by_name.merge!(other.all_classes_by_name)
127
- end
128
-
129
- def merge_loaded_files(other)
130
- @loaded_files.concat(other.loaded_files)
131
- raise InterpreterError, 'Cannot load multiple files after *LOAD instruction' if @loaded_files.length > @max_files_allowed
132
- end
133
-
134
- def has_pairs?
135
- @pairs.length.positive?
136
- end
137
-
138
- def has_class?(key)
139
- @classes_by_id.keys.include?(key) || @classes_by_name.keys.include?(key)
140
- end
141
-
142
- def has_array?(key)
143
- @arrays_by_id.keys.include?(key) || @arrays_by_name.keys.include?(key)
144
- end
145
-
146
- def has_user_method?(key)
147
- @methods_hash.keys.include?(key)
148
- end
149
-
150
- def add_to_index(item)
151
- @index << item
152
- end
153
-
154
- def user_method(key, val = nil)
155
- return @methods_hash[key] unless val
156
-
157
- @methods_hash[key] = val
158
- end
159
-
160
- def user_method_id(key, val)
161
- @methods_hash[key] = val
162
- @methods_by_id[key] = val
163
- end
164
-
165
- def class_list
166
- result = []
167
- @classes_by_id.values.each do |clazz|
168
- new_item = {}
169
- new_item[clazz.id] = class_to_hash(clazz)
170
- result << new_item
171
- end
172
- result
173
- end
174
-
175
- def method_list
176
- result = []
177
- @methods_by_id.values.each do |m|
178
- new_item = {}
179
- new_item[m.id] = method_to_hash(m)
180
- result << new_item
181
- end
182
- result
183
- end
184
-
185
- def file_list
186
- @loaded_files.dup
187
- end
188
-
189
- def id_list
190
- ids = {}
191
- ids['methods'] = @methods_by_id.keys.dup.sort!
192
- ids['classes'] = @classes_by_id.keys.dup.sort!
193
- ids
194
- end
195
-
196
- def name_list
197
- names = {}
198
- names['methods'] = @methods_hash.keys.dup.sort!
199
- names['classes'] = @classes_by_name.keys.dup.sort!
200
- names
201
- end
202
-
203
- def superclass_list
204
- result = {}
205
- @classes_by_id.each do |c|
206
- result[c[0]] = c[1].superclass
207
- end
208
- result
209
- end
210
-
211
- def assign_list
212
- result = {}
213
- @classes_by_id.each do |c|
214
- result[c[0]] = c[1].assign
215
- end
216
- result
217
- end
218
-
219
- def transform_list
220
- result = {}
221
- @methods_by_id.each do |c|
222
- result[c[0]] = c[1].transform
223
- end
224
- result
225
- end
226
-
227
- def allow_list
228
- result = {}
229
- @classes_by_id.each do |c|
230
- result[c[0]] = c[1].allow.nil? ? nil : c[1].allow.extract_hash
231
- end
232
- result
233
- end
234
-
235
- protected
236
-
237
- def all_classes_by_id
238
- @classes_by_id
239
- end
240
-
241
- def all_classes_by_name
242
- @classes_by_name
243
- end
244
-
245
- def all_pairs
246
- result = {}
247
- @pairs.keys.each do |k|
248
- result[k] = @pairs[k] unless k.start_with?('*')
249
- end
250
- result
251
- end
252
-
253
- private
254
-
255
- def class_to_hash(clazz)
256
- map = {}
257
- # name
258
- map['name'] = clazz.name
259
-
260
- # superclass
261
- map['superclass'] = clazz.superclass
262
-
263
- # assign
264
- if clazz.assign
265
- map['assign'] = clazz.assign
266
- end
267
-
268
- # allow
269
- if clazz.allow
270
- map['allow'] = clazz.allow.extract_hash
271
- end
272
-
273
- # expect
274
- if clazz.expect
275
- map['expect'] = clazz.expect.extract_hash
276
- end
277
-
278
- # content
279
- if clazz.content.length.positive?
280
- clazz.content.each do |item|
281
- map[item[0]] = item[1].extract_hash
282
- end
283
- end
284
-
285
- map
286
- end
287
-
288
- def method_to_hash(mthd)
289
- map = {}
290
- # name
291
- map['name'] = mthd.name
292
-
293
- # superclass
294
- map['transform'] = mthd.transform
295
-
296
- map
297
- end
298
-
299
- def new_map_item(key, value)
300
- map_item = Parsed::ParsedMapItem.new(self)
301
- map_item.pair = Parsed::ParsedPair.new(self)
302
- map_item.pair.key = key
303
- map_item.pair.valueItem = Parsed::ParsedValueItem.new(self)
304
- if value.is_a? Parsed::ParsedValue
305
- map_item.pair.valueItem.value = value
306
- else
307
- map_item.pair.valueItem.value = Parsed::ParsedValue.new(self)
308
- map_item.pair.valueItem.value.primitive = Parsed::ParsedPrimitive.new(self)
309
- map_item.pair.valueItem.value.primitive = Parsed::ParsedPrimitive.new(self)
310
- map_item.pair.valueItem.value.primitive.string = Parsed::ParsedString.new(value)
311
- map_item.pair.valueItem.value.primitive.text = value
312
- map_item.pair.valueItem.value.text = value
313
- end
314
- map_item
315
- end
316
- end
317
- end
318
- end
@@ -1,82 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # The MIT License (MIT)
4
- #
5
- # Copyright (c) 2019 NUM Technology Ltd
6
- #
7
- # Permission is hereby granted, free of charge, to any person obtaining a copy
8
- # of this software and associated documentation files (the "Software"), to deal
9
- # in the Software without restriction, including without limitation the rights
10
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
- # copies of the Software, and to permit persons to whom the Software is
12
- # furnished to do so, subject to the following conditions:
13
- #
14
- # The above copyright notice and this permission notice shall be included in
15
- # all copies or substantial portions of the Software.
16
- #
17
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
- # THE SOFTWARE.
24
-
25
- module MODL
26
- module Parser
27
- # This class handles the conversion of objects that refer to classes into instances of those classes.
28
- # It works recursively since class usage can be nested.
29
- class InstructionProcessor
30
- def self.process(global, obj)
31
- if obj.is_a? Hash
32
- nvals = {}
33
- obj.keys.each do |k|
34
- o = obj[k]
35
- if o.is_a? String
36
- nv = process_instruction(global, o)
37
- nvals[k] = nv unless nv.nil?
38
- else
39
- process(global, o)
40
- end
41
- end
42
- obj.merge!(nvals)
43
- elsif obj.is_a? Array
44
- i = 0
45
- while i < obj.length
46
- o = obj[i]
47
- if o.is_a? String
48
- nv = process_instruction(global, o)
49
- obj[i] = nv unless nv.nil?
50
- else
51
- process(global, o)
52
- end
53
- i += 1
54
- end
55
- end
56
- end
57
-
58
- def self.process_instruction(global, str)
59
- case str
60
- when '%*class'
61
- return global.class_list
62
- when '%*method'
63
- return global.method_list
64
- when '%*load'
65
- return global.file_list
66
- when '%*id'
67
- return global.id_list
68
- when '%*name'
69
- return global.name_list
70
- when '%*superclass'
71
- return global.superclass_list
72
- when '%*assign'
73
- return global.assign_list
74
- when '%*transform'
75
- return global.transform_list
76
- when '%*allow'
77
- return global.allow_list
78
- end
79
- end
80
- end
81
- end
82
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # The MIT License (MIT)
4
- #
5
- # Copyright (c) 2019 NUM Technology Ltd
6
- #
7
- # Permission is hereby granted, free of charge, to any person obtaining a copy
8
- # of this software and associated documentation files (the "Software"), to deal
9
- # in the Software without restriction, including without limitation the rights
10
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
- # copies of the Software, and to permit persons to whom the Software is
12
- # furnished to do so, subject to the following conditions:
13
- #
14
- # The above copyright notice and this permission notice shall be included in
15
- # all copies or substantial portions of the Software.
16
- #
17
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
- # THE SOFTWARE.
24
-
25
- require 'modl/parser/MODLParserListener'
26
- require 'modl/parser/MODLParserVisitor'
27
- require 'modl/parser/MODLLexer'
28
- require 'modl/parser/MODLParser'
29
- require 'modl/parser/class_processor'
30
- require 'modl/parser/orphan_handler'
31
- require 'modl/parser/parser'
32
- require 'json'
33
-
34
- module MODL
35
- # Interpreter-specific errors
36
- class InterpreterError < StandardError
37
- end
38
-
39
- class ParserError < StandardError
40
- end
41
-
42
- # This is the main Ruby Interpreter entry point. Supply a String containing MODL text and it will return a String
43
- # containing the JSON equivalent. The JSON isn't pretty-printed unless pretty is true
44
- class Interpreter
45
- def self.interpret(str, pretty = false)
46
- interpreted = MODL.parse(str)
47
- return interpreted if interpreted.is_a? String
48
-
49
- # Otherwise generate a JSON string.
50
- if pretty
51
- JSON.pretty_generate interpreted
52
- else
53
- JSON.generate interpreted
54
- end
55
- end
56
- end
57
-
58
- # Parse a MODL string and return a hash, array, or String depending on how the MODL is structured.
59
- def self.parse(string)
60
- # Parse the MODL string into a MODL::Parser::Parsed object.
61
- parsed = MODL::Parser::Parser.parse(string)
62
-
63
- # Check for orphan pairs and adopt them.
64
- parsed.structures = MODL::Parser::OrphanHandler.adopt(parsed.global, parsed.structures)
65
-
66
- # Convert the Parsed object into a simpler structure of and Array or Hash
67
- interpreted = parsed.extract_hash
68
-
69
- # Process any class definitions used by the MODL file.
70
- interpreted = MODL::Parser::ClassProcessor.process(parsed.global, interpreted)
71
- MODL::Parser::InstructionProcessor.process(parsed.global, interpreted)
72
- # If the result is a simple string then just return it.
73
- interpreted
74
- end
75
- end
@@ -1,138 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # The MIT License (MIT)
4
- #
5
- # Copyright (c) 2019 NUM Technology Ltd
6
- #
7
- # Permission is hereby granted, free of charge, to any person obtaining a copy
8
- # of this software and associated documentation files (the "Software"), to deal
9
- # in the Software without restriction, including without limitation the rights
10
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
- # copies of the Software, and to permit persons to whom the Software is
12
- # furnished to do so, subject to the following conditions:
13
- #
14
- # The above copyright notice and this permission notice shall be included in
15
- # all copies or substantial portions of the Software.
16
- #
17
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
- # THE SOFTWARE.
24
-
25
- module MODL
26
- module Parser
27
- # Represents a *class defined, or loaded by, a MODL document.
28
- class MODLClass
29
- attr_accessor :id
30
- attr_accessor :name
31
- attr_accessor :superclass
32
- attr_accessor :assign
33
- attr_accessor :content
34
- attr_accessor :allow
35
- attr_accessor :expect
36
-
37
- def initialize
38
- @content = {}
39
- end
40
-
41
- # Find a keylist of the right length from the *assign array of arrays.
42
- def keylist_of_length(len)
43
- return nil if @assign.nil?
44
-
45
- # *assign can support iteration, e.g. *assign=[[person*]]
46
- # so return a list of the right length in this case
47
- if @assign.length == 1 && @assign[0].length == 1 && @assign[0][0].end_with?('*')
48
- key = Sutil.head @assign[0][0]
49
- return Array.new(len, key)
50
- end
51
-
52
- @assign.each do |kl|
53
- return kl if kl.length == len
54
- end
55
-
56
- raise InterpreterError,
57
- 'Interpreter Error: No key list of the correct length in class ' + @id + ' - looking for one of length ' + len.to_s
58
- end
59
-
60
- def merge_content(new_value)
61
- @content.each do |k, v|
62
- new_value[k] = v.extract_hash unless new_value[k]
63
- end
64
- new_value
65
- end
66
-
67
- def name_or_id
68
- @name.nil? ? @id : @name
69
- end
70
- end
71
-
72
- # Extract a class from a ParsedPair object
73
- class ClassExtractor
74
- def self.extract(pair, global)
75
- return unless pair.type == 'class'
76
-
77
- clazz = MODLClass.new
78
- map = pair.map if pair.map
79
- map = pair.valueItem&.value&.map if pair.valueItem&.value&.map
80
-
81
- map.mapItems.each do |item|
82
- next unless item&.pair&.type
83
-
84
- case item&.pair&.type
85
- when 'id'
86
- str_value = item.pair.valueItem.value.primitive.string.string
87
- raise InterpreterError, 'Reserved class id - cannot redefine: ' + str_value if reserved?(str_value)
88
-
89
- clazz.id = str_value
90
- when 'name'
91
- str_value = item.pair.valueItem.value.primitive.string.string
92
- raise InterpreterError, 'Reserved class name - cannot redefine: ' + str_value if reserved?(str_value)
93
-
94
- clazz.name = str_value
95
- when 'superclass'
96
- str_value = item.pair.valueItem.value.primitive.string.string
97
- clazz.superclass = str_value
98
- when 'keylist'
99
- clazz.assign = item.pair.key_lists
100
- when 'allow'
101
- clazz.allow = item.pair.array if item.pair.array
102
- clazz.allow = item.pair.valueItem.value.array if item.pair.valueItem.value.array
103
- when 'expect'
104
- clazz.expect = item.pair.array if item.pair.array
105
- clazz.expect = item.pair.valueItem.value.array if item.pair.valueItem.value.array
106
- else
107
- clazz.content[item.pair.key] = item.pair.array if item.pair.array
108
- clazz.content[item.pair.key] = item.pair.map if item.pair.map
109
- clazz.content[item.pair.key] = item.pair.valueItem.value if item.pair.valueItem.value
110
- end
111
- end
112
-
113
- superclass = clazz.superclass
114
-
115
- if superclass && !reserved?(superclass) && !global.has_class?(superclass)
116
- raise InterpreterError, 'Invalid superclass: ' + superclass.to_s
117
- end
118
- raise InterpreterError, 'Missing id for class' if clazz.id.nil?
119
-
120
- # Make sure the class name isn't redefining an existing class
121
- if !global.has_class?(clazz.id) && !global.has_class?(clazz.name)
122
-
123
- # store the classes by id and name to make them easier to find later
124
- global.classs(clazz)
125
- else
126
- id = clazz.id.nil? ? 'undefined' : clazz.id
127
- name = clazz.name.nil? ? 'undefined' : clazz.name
128
- raise InterpreterError, 'Class name or id already defined - cannot redefine: ' + id + ', ' + name
129
- end
130
- end
131
-
132
- # Check for a reserved class name
133
- def self.reserved?(str)
134
- %w[map str arr num].include?(str)
135
- end
136
- end
137
- end
138
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # The MIT License (MIT)
4
- #
5
- # Copyright (c) 2019 NUM Technology Ltd
6
- #
7
- # Permission is hereby granted, free of charge, to any person obtaining a copy
8
- # of this software and associated documentation files (the "Software"), to deal
9
- # in the Software without restriction, including without limitation the rights
10
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
- # copies of the Software, and to permit persons to whom the Software is
12
- # furnished to do so, subject to the following conditions:
13
- #
14
- # The above copyright notice and this permission notice shall be included in
15
- # all copies or substantial portions of the Software.
16
- #
17
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
- # THE SOFTWARE.
24
-
25
- module MODL
26
- module Parser
27
- # Extracts an index definition from a ParsedPair
28
- class IndexExtractor
29
- def self.extract(pair, global)
30
- item = pair.valueItem if pair.valueItem
31
- item = pair.array if pair.array
32
-
33
- # collect all values from the object
34
- if item.is_a? Parsed::ParsedValueItem
35
- if item&.value&.text
36
- global.add_to_index(item.value.text)
37
- elsif item&.value&.array
38
- item.value.array.abstractArrayItems.each do |avi|
39
- global.add_to_index(avi.arrayValueItem)
40
- end
41
- elsif item&.value&.nbArray
42
- item.value.nbArray.arrayItems.each do |avi|
43
- global.add_to_index(avi.arrayValueItem)
44
- end
45
- end
46
- elsif item.is_a? Parsed::ParsedArray
47
- item.abstractArrayItems.each do |avi|
48
- global.add_to_index(avi.arrayValueItem)
49
- end
50
- end
51
- end
52
- end
53
- end
54
- end