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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: edaf87097f3f827795fdeff49c22f3acb3e25ec92acf2bf177ab1af9f881ae9e
4
- data.tar.gz: da67d0d410dbad33b336daf1bbf424912e6cbca52d5ef939b42908af445d1fad
3
+ metadata.gz: 19413632838d38b40c5079a2b4c4551681ba94fc67c03a9b5aba98ef3bab522b
4
+ data.tar.gz: 74648b6833fdd3a9562bfde9ce8ddbaeea71439b751d19cd4487d5c586f918e1
5
5
  SHA512:
6
- metadata.gz: dd2e39df266e049f744a927ef12ffe63dbc2e1aa3af60e82b3c964104c6c85cc1c7822318ef855b7c7cd494d1eea1d04fa628111b2d3506cf5590d906e1f14e2
7
- data.tar.gz: 7f1c74734687b3d9ab94b9e6757d4fcf435721366b1267d2b2ae4857f8a1636f6f4f9b7e8333aedb46614691a5f8c50a1871470795fba670a366f7d6c0c186fc
6
+ metadata.gz: a2e31d1efa2d9668c94f503f1b0d5cdc19c9ea484dd85314e6697a6647ef44bed2213515ad3031839e38bf459a7e68497434b195f2f9cf5e54ce81203bfd03e0
7
+ data.tar.gz: c9dec885b8ea5acc8799c405379f3848dbac48f5dc919ae27f34d2d2d2bc8dda1fdee18620477f3867e747e00ba0baf2b940b1f62d29c7fa71055bb857cedc5f
data/CHANGELOG.md CHANGED
@@ -1,151 +1,3 @@
1
- 0.3.26
2
- ===
3
- - Remove `*expect`
4
- - Fix problem with references in classes.
5
-
6
- 0.3.25
7
- ===
8
- - Update Rake due to security advisory.
9
-
10
- 0.3.24
11
- ===
12
- - Use base_tests from the grammar repo.
13
- - Updated grammar to support minified MODL.
14
- - Bug fixes for handling minified MODL.
15
-
16
- 0.3.23
17
- ===
18
- - Add support for 5- and 6-digit unicode escape sequences.
19
-
20
- 0.3.22
21
- ===
22
- - Two bug fixes - quoted strings, and incomplete strings for certain output situations.
23
-
24
- 0.3.21
25
- ===
26
- - Bugfix for `*assign` processing.
27
-
28
- 0.3.20
29
- ===
30
- - Support escaping unicode escape sequences so they are not replaced by unicode characters.
31
-
32
- 0.3.19
33
- ===
34
- - Fix bug with `*assign` when there is only 1 item in the array.
35
-
36
- 0.3.18
37
- ===
38
- - Fix problems with `*assign`.
39
-
40
- 0.3.17
41
- ===
42
- - Remove support for `*array`.
43
- - Add support for unicode escape sequences including `~unnnn` and `\unnnn`
44
- - Update `*assign` processing to support a more compact form
45
-
46
- 0.3.16
47
- ===
48
- - Use latest ruby runtime.
49
- - Add support for `*array` keyword.
50
-
51
- 0.3.15
52
- ===
53
- - Interpreter Error: undefined method `text' for nil:NilClass. GitHub issue #23
54
- - Fixed some NOT IMPLEMENTED sections for *method interpretation. GitHub issue #25
55
- - Standardise the error messages to match the Java interpreter.
56
-
57
- 0.3.14
58
- ===
59
- - MODL Syntax Versioning errors update. GitHub issue #11
60
- - Support for escaped % characters - GitHub issue #43
61
-
62
- 0.3.13
63
- ===
64
- - Added missing exceptions for Orphan Pairs
65
-
66
- 0.3.12
67
- ===
68
- - Use file cache on load error - GitHub issue #20
69
- - Error converting value to number - GitHub issue #21
70
- - Problem with punycode - GitHub issue #22
71
- - Handle orphan pairs - adopt then into a map
72
-
73
- 0.3.11
74
- ===
75
- - Support conditional file loading.
76
- - Updated to latest grammar.
77
-
78
- 0.3.10
79
- ===
80
- - Fix GitHub issue #19 - Checking value of object reference in conditional
81
-
82
- 0.3.9
83
- ===
84
- - Fix GitHub Issue #18 - Quoted strings not handled correctly in references
85
-
86
- 0.3.8
87
- ===
88
- - Add MIT license to all non-auto-generated Ruby files.
89
- - Use latest ANTLR4 Ruby runtime - previous version didn't build on AWS.
90
-
91
- 0.3.7
92
- ===
93
- - Update to latest antlr4-ruby-runtime for performance improvements
94
- - Fixed some failing base_tests
95
- - Fixed processing of superclass type conversions.
96
- - Fixed file caching issue - GitHub issue#1
97
- - Fixed GitHub issue#15 unicode problem.
98
- - Fixed GitHub issue#9 *LOAD problem
99
- - Fixed bug in error tests handling
100
- - Fixed stack too deep error for rafs such as `%ref%`
101
- - Fixed GitHub issue#13 No output from objects in loaded file.
102
- - Fixed GitHub issue#14 method chaining problem.
103
- - Correct handling of invalid pair keys.
104
- - Fix file encoding problem for error_tests.json on MS Windows.
105
-
106
- 0.3.6
107
- ===
108
- - Use latest ANTLR4 Ruby.stg updated by Cameron Dutro.
109
- - Use antrl4-runtime v0.2.2 which fixes some issues around Array2DHashSet
110
- - Fixed a failing error test due to incorrect value type for a `*class` with supertype `num`.
111
- - Corrected the ordering of fields within a class.
112
- - Return `null` for empty output rather than `""`
113
- - Fixed GitHub issue#4 - improved error reporting.
114
-
115
- 0.3.5
116
- ===
117
- - Fixed another bug with class handling to expand classes properly.
118
-
119
- 0.3.4
120
- ===
121
- - Fixed a bug with class handling to expand classes properly.
122
- - Add `*expect` to the output for the `%*class` instruction.
123
-
124
- 0.3.3
125
- ===
126
- - Change module name to MODL from Modl.
127
- - Support simpler usage, i.e. `x = MODL.parse(str)`. README.md updated accordingly.
128
- - Ignore *allow and *expect for now, except when used as `x=%*allow` or `x=%*expect`. Proper implementation will follow later.
129
- - Fixed a NilClass exception.
130
- - Disabled file caching due to garbage collection and other issues. See issue#1.
131
- - Grammar update to catch errors from unparsed MODL input.
132
-
133
- 0.3.2
134
- ===
135
- - Update to latest ANTLR4 Runtime
136
-
137
- 0.3.1
138
- ===
139
- - Update to latest ANTLR4 Runtime
140
-
141
- 0.3.0
142
- ===
143
- - First working MODL interpreter for Ruby
144
-
145
- 0.2.0
146
- ===
147
- - Hello world.
148
-
149
- 0.1.0
1
+ 0.0.1
150
2
  ===
151
3
  - Initial release
data/Gemfile CHANGED
@@ -1,9 +1,11 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in modl.gemspec
4
6
  group :development, :test do
5
- gem 'ruby-debug-ide'
6
7
  gem 'debase'
8
+ gem 'ruby-debug-ide'
7
9
  end
8
10
 
9
11
  gemspec
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2019 NUM Technology Ltd
3
+ Copyright (c) 2022 NUM Technology Ltd
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
- # MODL::Parser
1
+ # MODL::Interpreter
2
+
3
+ This Ruby gem is a MODL interpreter and requires Ruby 2.6.0.
2
4
 
3
- This Ruby gem can be used as the base for a MODL interpreter. It contains the Lexer, Parser, and other supporting classes generated by the ANTLR4 Ruby language target.
4
5
  ## Installation
5
6
 
6
7
  Add this line to your application's Gemfile:
@@ -21,30 +22,37 @@ Or clone the repository and build and install it yourself as:
21
22
 
22
23
  $ sudo rake install
23
24
 
24
- You will also need to install the antlr4-ruby-runtime gem that this depends on. See https://github.com/MODLanguage/antlr4-ruby-runtime
25
25
  ## Usage
26
26
 
27
+ In `irb`:
28
+
29
+ ```ruby
30
+ 2.6.0 :001 > require 'modl'
31
+ => true
32
+ 2.6.0 :002 > MODL.parse 'a=b'
33
+ => {"a"=>"b"}
34
+ 2.6.0 :003 >
35
+ ```
36
+ In a Ruby file:
37
+
27
38
  ```ruby
28
39
  require 'modl'
29
40
 
30
41
  str='s=MODL data'
31
-
32
- result = MODL.parse(str)
33
- jsonStr = JSON.pretty_generate(result)
34
- puts jsonStr
42
+ pretty = true
43
+ result = MODL.parse str
44
+ puts result
35
45
 
36
46
  ```
37
47
  where `str` is the modl to be interpreted.
38
48
 
39
49
  ## Development
40
50
 
41
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
42
-
43
51
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
44
52
 
45
53
  ## Contributing
46
54
 
47
- Bug reports and pull requests are welcome on GitHub at https://github.com/MODLanguage/ruby-interpreter. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
55
+ Bug reports and pull requests are welcome on GitHub at https://github.com/MODLanguage/ruby-modl. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
48
56
 
49
57
  ## License
50
58
 
@@ -52,4 +60,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
52
60
 
53
61
  ## Code of Conduct
54
62
 
55
- Everyone interacting in the MODL::Parser project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/modl-parser/blob/master/CODE_OF_CONDUCT.md).
63
+ Everyone interacting in the MODL::Interpreter project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/modl-parser/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ # The MODL namespace
6
+ module MODL
7
+ # Interpreter-specific errors
8
+ class ParserError < StandardError
9
+ end
10
+
11
+ # This is the main Ruby Interpreter entry point. Supply a String containing
12
+ # MODL text and it will return a String containing the JSON equivalent.
13
+ # The JSON isn't pretty-printed unless pretty is true
14
+ module Interpreter
15
+ def self.interpret_to_json_string(str, pretty = false)
16
+ json_obj = interpret_to_object str
17
+ pretty ? JSON.pretty_generate(json_obj) : JSON.generate(json_obj)
18
+ end
19
+
20
+ def self.interpret_to_object(str)
21
+ interpret(str).to_j
22
+ end
23
+
24
+ def self.interpret(str)
25
+ MODL::Parser.parse_modl str
26
+ end
27
+ end
28
+
29
+ # MODL String to Ruby Hash/Array/primitive
30
+ def self.parse(str)
31
+ MODL::Interpreter.interpret_to_object str
32
+ end
33
+
34
+ # Ruby Hash/Array/primitive to MODL
35
+ def self.generate(obj)
36
+ MODL::Model::Modl.new(MODL::Model.to_modl(obj)).to_m
37
+ end
38
+ end
@@ -0,0 +1,264 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MODL
4
+ # A Model module for MODL
5
+ module Model
6
+ # The root of a MODL object
7
+ class Modl
8
+ attr_reader :value
9
+
10
+ def initialize(value)
11
+ @value = value
12
+ end
13
+
14
+ def to_s
15
+ if @value.instance_of? Array
16
+ @value.map(&:to_s)
17
+ else
18
+ "Modl: #{@value}"
19
+ end
20
+ end
21
+
22
+ def to_j
23
+ @value.nil? ? 'null' : @value.to_j
24
+ end
25
+
26
+ def to_m
27
+ if @value.instance_of?(ModlMap)
28
+ @value.items.map(&:to_m).join(';')
29
+ else
30
+ @value.to_m
31
+ end
32
+ end
33
+ end
34
+
35
+ # A MODL Array
36
+ class ModlArray
37
+ attr_reader :items
38
+
39
+ def initialize(items)
40
+ @items = items
41
+ end
42
+
43
+ def to_s
44
+ items = @items.map(&:to_s)
45
+ "ModlArray: #{items}"
46
+ end
47
+
48
+ def to_j
49
+ @items.map(&:to_j)
50
+ end
51
+
52
+ def to_m
53
+ list = @items.map(&:to_m).join ';'
54
+ "[#{list}]"
55
+ end
56
+ end
57
+
58
+ # A MODL Map
59
+ class ModlMap
60
+ attr_reader :items
61
+
62
+ def initialize(items)
63
+ @items = items
64
+ end
65
+
66
+ def to_s
67
+ items = @items.map(&:to_s)
68
+ "ModlMap: #{items}"
69
+ end
70
+
71
+ def to_j
72
+ result = @items.map { |p| [p.key, p.value.to_j] }
73
+ result.to_h
74
+ end
75
+
76
+ def to_m
77
+ modl = @items.map(&:to_m).join ';'
78
+ "(#{modl})"
79
+ end
80
+ end
81
+
82
+ # A MODL Primitive
83
+ class ModlPrimitive
84
+ attr_reader :value
85
+
86
+ def initialize(value)
87
+ @value = value
88
+ end
89
+
90
+ def to_s
91
+ "ModlPrimitive: #{@value}"
92
+ end
93
+
94
+ def to_m
95
+ @value.to_s
96
+ end
97
+ end
98
+
99
+ # A MODL PAir
100
+ class ModlPair
101
+ attr_reader :key, :value
102
+
103
+ def initialize(key, value)
104
+ @key = key
105
+ @value = value
106
+ end
107
+
108
+ def to_s
109
+ "ModlPair: #{key}=#{@value}"
110
+ end
111
+
112
+ def to_j
113
+ { @key => @value.to_j }
114
+ end
115
+
116
+ def to_m
117
+ key = UTIL.non_string_primitive?(@key) ? "\"#{@key}\"" : @key
118
+ if @value.instance_of?(ModlPair)
119
+ "#{key}(#{@value.to_m})"
120
+ elsif @value.instance_of?(ModlMap) || @value.instance_of?(ModlArray)
121
+ "#{key}#{@value.to_m}"
122
+ else
123
+ "#{key}=#{@value.to_m}"
124
+ end
125
+ end
126
+ end
127
+
128
+ # A MODL FLOAT
129
+ class ModlFloat
130
+ attr_reader :value
131
+
132
+ def initialize(value)
133
+ @value = value
134
+ end
135
+
136
+ def to_s
137
+ "ModlFloat: #{@value}"
138
+ end
139
+
140
+ def to_j
141
+ @value
142
+ end
143
+
144
+ def to_m
145
+ format('%.16G', @value).sub('E+', 'E')
146
+ end
147
+ end
148
+
149
+ # A MODL Integer
150
+ class ModlInteger
151
+ attr_reader :value
152
+
153
+ def initialize(value)
154
+ @value = value
155
+ end
156
+
157
+ def to_s
158
+ "ModlInteger: #{@value}"
159
+ end
160
+
161
+ def to_j
162
+ @value
163
+ end
164
+
165
+ def to_m
166
+ @value.to_s
167
+ end
168
+ end
169
+
170
+ # A MODL String
171
+ class ModlString
172
+ attr_reader :value
173
+
174
+ def initialize(value)
175
+ @value = value
176
+ end
177
+
178
+ def to_s
179
+ "ModlString: #{@value}"
180
+ end
181
+
182
+ def to_j
183
+ @value
184
+ end
185
+
186
+ def to_m
187
+ UTIL.escape_and_quote @value
188
+ end
189
+ end
190
+
191
+ # A MODL Quoted String
192
+ class ModlQuoted
193
+ attr_reader :value
194
+
195
+ def initialize(value)
196
+ @value = value
197
+ end
198
+
199
+ def to_s
200
+ "ModlQuoted: #{@value}"
201
+ end
202
+
203
+ def to_j
204
+ @value
205
+ end
206
+
207
+ def to_m
208
+ UTIL.escape_and_quote @value
209
+ end
210
+ end
211
+
212
+ # A MODL Boolean or NULL
213
+ class ModlBoolNull
214
+ def initialize(value)
215
+ @value = value
216
+ end
217
+
218
+ MODL_NULL = ModlBoolNull.new nil
219
+ MODL_TRUE = ModlBoolNull.new true
220
+ MODL_FALSE = ModlBoolNull.new false
221
+
222
+ def to_s
223
+ "ModlBoolNull: #{@value}"
224
+ end
225
+
226
+ def to_j
227
+ @value
228
+ end
229
+
230
+ def to_m
231
+ @value.nil? ? 'null' : @value
232
+ end
233
+ end
234
+
235
+ # Convert a Ruby Hash/Array/Primitive to a Modl object.
236
+ def self.to_modl(obj)
237
+ if obj.instance_of? Float
238
+ ModlFloat.new obj
239
+ elsif obj.instance_of? Integer
240
+ ModlInteger.new obj
241
+ elsif obj.instance_of? String
242
+ ModlString.new obj
243
+ elsif obj.instance_of? Hash
244
+ if obj.keys.length == 1
245
+ key = obj.keys[0]
246
+ ModlPair.new key, to_modl(obj[key])
247
+ else
248
+ ModlMap.new(obj.keys.map { |k| ModlPair.new k, to_modl(obj[k]) })
249
+ end
250
+ elsif obj.instance_of? Array
251
+ ModlArray.new(obj.map { |i| to_modl i })
252
+ elsif obj.instance_of? TrueClass
253
+ ModlBoolNull::MODL_TRUE
254
+ elsif obj.instance_of? FalseClass
255
+ ModlBoolNull::MODL_FALSE
256
+ elsif obj.instance_of? NilClass
257
+ ModlBoolNull::MODL_NULL
258
+ else
259
+ puts "Cannot handle #{obj}"
260
+ exit
261
+ end
262
+ end
263
+ end
264
+ end