modl 0.3.25 → 0.3.27

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -140
  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 -84
  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 -1470
  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: 6dea81884e2aa76c3e7131afd53ab68641622035cf63f21b687b4b2d5003e090
4
- data.tar.gz: 9bfa08742c36d41ca903abe5bd66220e099ad32ef2ebfa12c18a092141dca340
3
+ metadata.gz: 19413632838d38b40c5079a2b4c4551681ba94fc67c03a9b5aba98ef3bab522b
4
+ data.tar.gz: 74648b6833fdd3a9562bfde9ce8ddbaeea71439b751d19cd4487d5c586f918e1
5
5
  SHA512:
6
- metadata.gz: f039c1b05655c54b66fb635f71b3a7a7a89d2d989e3f196744be3d90077a54b785771ac755120bdadb9849654b2f0c8a7d57195e3716bc09543ea50f804497ad
7
- data.tar.gz: 62306fdd0ecb9bee034d7dd9f3bbb522d33f9a309aab51e976089ba1ea3b6d30be8453edc8d73d16d33d03d9b85627764609a46d9930aa927350791c915d90b0
6
+ metadata.gz: a2e31d1efa2d9668c94f503f1b0d5cdc19c9ea484dd85314e6697a6647ef44bed2213515ad3031839e38bf459a7e68497434b195f2f9cf5e54ce81203bfd03e0
7
+ data.tar.gz: c9dec885b8ea5acc8799c405379f3848dbac48f5dc919ae27f34d2d2d2bc8dda1fdee18620477f3867e747e00ba0baf2b940b1f62d29c7fa71055bb857cedc5f
data/CHANGELOG.md CHANGED
@@ -1,142 +1,3 @@
1
- 0.3.24
2
- ===
3
- - Use base_tests from the grammar repo.
4
- - Updated grammar to support minified MODL.
5
- - Bug fixes for handling minified MODL.
6
-
7
- 0.3.23
8
- ===
9
- - Add support for 5- and 6-digit unicode escape sequences.
10
-
11
- 0.3.22
12
- ===
13
- - Two bug fixes - quoted strings, and incomplete strings for certain output situations.
14
-
15
- 0.3.21
16
- ===
17
- - Bugfix for `*assign` processing.
18
-
19
- 0.3.20
20
- ===
21
- - Support escaping unicode escape sequences so they are not replaced by unicode characters.
22
-
23
- 0.3.19
24
- ===
25
- - Fix bug with `*assign` when there is only 1 item in the array.
26
-
27
- 0.3.18
28
- ===
29
- - Fix problems with `*assign`.
30
-
31
- 0.3.17
32
- ===
33
- - Remove support for `*array`.
34
- - Add support for unicode escape sequences including `~unnnn` and `\unnnn`
35
- - Update `*assign` processing to support a more compact form
36
-
37
- 0.3.16
38
- ===
39
- - Use latest ruby runtime.
40
- - Add support for `*array` keyword.
41
-
42
- 0.3.15
43
- ===
44
- - Interpreter Error: undefined method `text' for nil:NilClass. GitHub issue #23
45
- - Fixed some NOT IMPLEMENTED sections for *method interpretation. GitHub issue #25
46
- - Standardise the error messages to match the Java interpreter.
47
-
48
- 0.3.14
49
- ===
50
- - MODL Syntax Versioning errors update. GitHub issue #11
51
- - Support for escaped % characters - GitHub issue #43
52
-
53
- 0.3.13
54
- ===
55
- - Added missing exceptions for Orphan Pairs
56
-
57
- 0.3.12
58
- ===
59
- - Use file cache on load error - GitHub issue #20
60
- - Error converting value to number - GitHub issue #21
61
- - Problem with punycode - GitHub issue #22
62
- - Handle orphan pairs - adopt then into a map
63
-
64
- 0.3.11
65
- ===
66
- - Support conditional file loading.
67
- - Updated to latest grammar.
68
-
69
- 0.3.10
70
- ===
71
- - Fix GitHub issue #19 - Checking value of object reference in conditional
72
-
73
- 0.3.9
74
- ===
75
- - Fix GitHub Issue #18 - Quoted strings not handled correctly in references
76
-
77
- 0.3.8
78
- ===
79
- - Add MIT license to all non-auto-generated Ruby files.
80
- - Use latest ANTLR4 Ruby runtime - previous version didn't build on AWS.
81
-
82
- 0.3.7
83
- ===
84
- - Update to latest antlr4-ruby-runtime for performance improvements
85
- - Fixed some failing base_tests
86
- - Fixed processing of superclass type conversions.
87
- - Fixed file caching issue - GitHub issue#1
88
- - Fixed GitHub issue#15 unicode problem.
89
- - Fixed GitHub issue#9 *LOAD problem
90
- - Fixed bug in error tests handling
91
- - Fixed stack too deep error for rafs such as `%ref%`
92
- - Fixed GitHub issue#13 No output from objects in loaded file.
93
- - Fixed GitHub issue#14 method chaining problem.
94
- - Correct handling of invalid pair keys.
95
- - Fix file encoding problem for error_tests.json on MS Windows.
96
-
97
- 0.3.6
98
- ===
99
- - Use latest ANTLR4 Ruby.stg updated by Cameron Dutro.
100
- - Use antrl4-runtime v0.2.2 which fixes some issues around Array2DHashSet
101
- - Fixed a failing error test due to incorrect value type for a `*class` with supertype `num`.
102
- - Corrected the ordering of fields within a class.
103
- - Return `null` for empty output rather than `""`
104
- - Fixed GitHub issue#4 - improved error reporting.
105
-
106
- 0.3.5
107
- ===
108
- - Fixed another bug with class handling to expand classes properly.
109
-
110
- 0.3.4
111
- ===
112
- - Fixed a bug with class handling to expand classes properly.
113
- - Add `*expect` to the output for the `%*class` instruction.
114
-
115
- 0.3.3
116
- ===
117
- - Change module name to MODL from Modl.
118
- - Support simpler usage, i.e. `x = MODL.parse(str)`. README.md updated accordingly.
119
- - Ignore *allow and *expect for now, except when used as `x=%*allow` or `x=%*expect`. Proper implementation will follow later.
120
- - Fixed a NilClass exception.
121
- - Disabled file caching due to garbage collection and other issues. See issue#1.
122
- - Grammar update to catch errors from unparsed MODL input.
123
-
124
- 0.3.2
125
- ===
126
- - Update to latest ANTLR4 Runtime
127
-
128
- 0.3.1
129
- ===
130
- - Update to latest ANTLR4 Runtime
131
-
132
- 0.3.0
133
- ===
134
- - First working MODL interpreter for Ruby
135
-
136
- 0.2.0
137
- ===
138
- - Hello world.
139
-
140
- 0.1.0
1
+ 0.0.1
141
2
  ===
142
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