delorean_lang 2.1.0 → 2.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c38ab0abe7bac9f36adbc22664d1efc5a01216d032fa8b8a079ecc640a560b7
4
- data.tar.gz: c990d13bfae100045288a5139614ff72e3af2a0a9e89ff87790e8b717b19f39c
3
+ metadata.gz: aefcc15664badb32e23cd629f7888a3984cf3fd0c01a351b652a71094c5ff3fc
4
+ data.tar.gz: b3391aa0c8a00c49487ba6039838e9fd1e98f172539e06bbbb810b8c9e8cc737
5
5
  SHA512:
6
- metadata.gz: 64ff3320a7722c5017eb2f0a366d21a1fa5b20173e4675cd1316dae14790676442787e164ea4e01c4ce2ae7f91a06eb9716e3ddecf8c0801e5e33801d105919a
7
- data.tar.gz: a020a58b04d8d067b44c977fce93927c2fed8e5bb6454c18cb01c72edbeb58321a00395d1bb258fd556023b309d0b8aedcfaeded789c43cda1cd72ea1b541138
6
+ metadata.gz: beea3a643c91eaa8374ce126d0e07836545b7e141174ec38a05030b0b45b087fc48ba2ad880ce65a101125de9889c9ff67cfe786e752b0ebfff6127dbbc56633
7
+ data.tar.gz: f3562421c5d037bf42da11f215b5f2c6d78c5c9987db1c0e1efdecaeb8c33c7f9ad38ad2b63db9b2d137b7179552b47ef99f0eb88d031d1ea98fb1fb9409f0c3
@@ -0,0 +1,2 @@
1
+ .gitlab-ci.yml
2
+ .gitlab
@@ -2,6 +2,7 @@ require: rubocop-performance
2
2
  inherit_from: .rubocop_todo.yml
3
3
 
4
4
  AllCops:
5
+ TargetRubyVersion: 2.4
5
6
  Exclude:
6
7
  - 'db/**/*'
7
8
  - 'spec/dummy/**/*'
@@ -14,7 +15,7 @@ Style/StringLiterals:
14
15
  Enabled: true
15
16
  EnforcedStyle: single_quotes
16
17
 
17
- Metrics/LineLength:
18
+ Layout/LineLength:
18
19
  Max: 80
19
20
  Exclude:
20
21
  - 'spec/**/*'
@@ -41,7 +42,7 @@ Style/TrailingCommaInHashLiteral:
41
42
  Style/FrozenStringLiteralComment:
42
43
  EnforcedStyle: always
43
44
 
44
- Layout/IndentHeredoc:
45
+ Layout/HeredocIndentation:
45
46
  Exclude:
46
47
  - 'spec/eval_spec.rb'
47
48
 
@@ -1,13 +1,14 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2019-04-16 19:29:23 +0300 using RuboCop version 0.67.2.
3
+ # on 2019-10-24 17:42:20 +0300 using RuboCop version 0.75.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
9
  # Offense count: 3
10
- Lint/HandleExceptions:
10
+ # Configuration parameters: AllowComments.
11
+ Lint/SuppressedException:
11
12
  Exclude:
12
13
  - 'spec/parse_spec.rb'
13
14
 
@@ -21,39 +22,38 @@ Lint/ShadowedException:
21
22
  Exclude:
22
23
  - 'lib/delorean/engine.rb'
23
24
 
24
- # Offense count: 5
25
+ # Offense count: 6
26
+ # Configuration parameters: AllowKeywordBlockArguments.
25
27
  Lint/UnderscorePrefixedVariableName:
26
28
  Exclude:
27
29
  - 'lib/delorean/base.rb'
28
30
 
29
- # Offense count: 66
30
- # Configuration parameters: CheckForMethodsWithNoSideEffects.
31
- Lint/Void:
31
+ # Offense count: 1
32
+ # Cop supports --auto-correct.
33
+ # Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
34
+ Lint/UnusedBlockArgument:
32
35
  Exclude:
33
- - 'spec/dev_spec.rb'
34
- - 'spec/eval_spec.rb'
35
- - 'spec/func_spec.rb'
36
- - 'spec/parse_spec.rb'
36
+ - 'lib/delorean/cache.rb'
37
37
 
38
- # Offense count: 19
38
+ # Offense count: 24
39
39
  Metrics/AbcSize:
40
- Max: 250
40
+ Max: 173
41
41
 
42
42
  # Offense count: 2
43
43
  # Configuration parameters: CountComments.
44
44
  Metrics/ClassLength:
45
45
  Max: 300
46
46
 
47
- # Offense count: 6
47
+ # Offense count: 8
48
48
  Metrics/CyclomaticComplexity:
49
- Max: 15
49
+ Max: 13
50
50
 
51
- # Offense count: 16
51
+ # Offense count: 22
52
52
  # Configuration parameters: CountComments, ExcludedMethods.
53
53
  Metrics/MethodLength:
54
- Max: 300
54
+ Max: 253
55
55
 
56
- # Offense count: 4
56
+ # Offense count: 6
57
57
  Metrics/PerceivedComplexity:
58
58
  Max: 15
59
59
 
@@ -62,19 +62,10 @@ Naming/AccessorMethodName:
62
62
  Exclude:
63
63
  - 'lib/delorean/debug.rb'
64
64
 
65
- # Offense count: 4
66
- # Configuration parameters: PreferredName.
67
- Naming/RescuedExceptionsVariableName:
68
- Exclude:
69
- - 'lib/delorean/base.rb'
70
- - 'lib/delorean/engine.rb'
71
- - 'spec/eval_spec.rb'
72
- - 'spec/parse_spec.rb'
73
-
74
65
  # Offense count: 12
75
66
  # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
76
67
  # AllowedNames: io, id, to, by, on, in, at, ip, db
77
- Naming/UncommunicativeMethodParamName:
68
+ Naming/MethodParameterName:
78
69
  Exclude:
79
70
  - 'lib/delorean/base.rb'
80
71
  - 'lib/delorean/debug.rb'
@@ -89,12 +80,11 @@ Style/ClassVars:
89
80
  - 'lib/delorean/nodes.rb'
90
81
  - 'spec/spec_helper.rb'
91
82
 
92
- # Offense count: 3
83
+ # Offense count: 2
93
84
  # Configuration parameters: MinBodyLength.
94
85
  Style/GuardClause:
95
86
  Exclude:
96
87
  - 'lib/delorean/engine.rb'
97
- - 'lib/delorean/model.rb'
98
88
 
99
89
  # Offense count: 1
100
90
  Style/MultilineBlockChain:
data/Gemfile CHANGED
@@ -7,6 +7,5 @@ gemspec
7
7
 
8
8
  group :development, :test do
9
9
  gem 'benchmark-ips'
10
- gem 'pry'
11
- gem 'rspec-instafail', require: false
10
+ gem 'simplecov'
12
11
  end
data/README.md CHANGED
@@ -29,7 +29,7 @@ Or add it to your `Gemfile`, etc.
29
29
 
30
30
  engine.parse my_code
31
31
 
32
- engine.evaluate("NodeB", %w{attr1 attr2 attr3})
32
+ engine.evaluate("NodeB", %w{attr1 attr2 attr3}, {"param"=>15})
33
33
 
34
34
  ## The Delorean Language
35
35
 
@@ -125,12 +125,12 @@ input of `age = 10` will evaluate to `true`. Whereas,
125
125
 
126
126
  You can use `(ERR())` to add a breakpoint:
127
127
 
128
- ```
129
- USInfo:
130
- age = ?
131
- teen_max = 19
132
- teen_min = 13
133
- is_teenager = (ERR()) && age >= teen_min && age <= teen_max
128
+ ```
129
+ USInfo:
130
+ age = ?
131
+ teen_max = 19
132
+ teen_min = 13
133
+ is_teenager = (ERR()) && age >= teen_min && age <= teen_max
134
134
 
135
135
  ```
136
136
 
@@ -230,18 +230,16 @@ You can use blocks in your Delorean code:
230
230
  ```ruby
231
231
  ExampleScript:
232
232
  a = [1, 2, 3]
233
- b = c.any? { |v| v > 2 }
234
- b2 = c.any? do |v| v > 2 end
235
-
236
- c = a.reduce(0) { |sum, el|
237
- sum + el
238
- }
239
- c2 = a.reduce() do |sum, el|
240
- sum + el
241
- end
233
+ b = c.any?
234
+ item =?
235
+ result = item > 2
236
+ c = a.reduce(0)
237
+ sum =?
238
+ num =?
239
+ result = sum + num
242
240
  ```
243
241
 
244
- Note that `do ... end` syntax is not yet supported
242
+ Note that `do ... end` syntax is not supported
245
243
 
246
244
  ### Caching
247
245
 
@@ -277,7 +275,10 @@ Delorean expects it to have methods with following signatures:
277
275
  ```ruby
278
276
 
279
277
  cache_item(klass:, cache_key:, item:)
278
+
279
+ fetch_item(klass:, cache_key:, default:)
280
280
  fetch_item(klass:, cache_key:, default:)
281
+
281
282
  cache_key(klass:, method_name:, args:)
282
283
  clear!(klass:)
283
284
  clear_all!
@@ -287,6 +288,45 @@ Delorean expects it to have methods with following signatures:
287
288
 
288
289
  ```
289
290
 
291
+ ### Node level caching
292
+
293
+ You can enable caching for a Delorean node with `_cache = true` attribute.
294
+
295
+ ```ruby
296
+ ExampleScript:
297
+ param1 =?
298
+ _cache = true
299
+ a = Dummy.heres_my_number(867, 5309)
300
+ b = DummyModule.heres_my_number(867, 5309)
301
+ result = b
302
+ ```
303
+
304
+ When node is called, Delorean would check if there is a cached result for a
305
+ combination of node parameters values and the attribute that is to be returned.
306
+
307
+ ```ruby
308
+ ExampleScript(param1=1).result # Will calculate result and cache it for calls with `param1=1`
309
+ ExampleScript(param1=1).result # Will fetch the cached result
310
+ ExampleScript(param1=2).result # Will calculate result and cache it for calls with `param1=2`
311
+ ```
312
+
313
+
314
+ #### Custom Node level caching policy
315
+
316
+ You can override the callback that Delorean calls before performing the caching.
317
+ The callback should return a hash with `:cache` key.
318
+ If `cache:` is false, then Delorean wouldn't fetch result from cache or perform caching.
319
+
320
+ ```ruby
321
+ ::Delorean::Cache.node_cache_callback = lambda do |klass:, method:, params:|
322
+ {
323
+ cache: true,
324
+ }
325
+ end
326
+
327
+ # See lib/delorean/cache.rb
328
+
329
+ ```
290
330
 
291
331
  TODO: provide details
292
332
 
@@ -2,6 +2,12 @@
2
2
 
3
3
  require File.expand_path('lib/delorean/version', __dir__)
4
4
 
5
+ git_tracked_files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
6
+ gem_ignored_files = `git ls-files -i -X .gemignore`.split(
7
+ $OUTPUT_RECORD_SEPARATOR
8
+ )
9
+ files = git_tracked_files - gem_ignored_files
10
+
5
11
  Gem::Specification.new do |gem|
6
12
  gem.authors = ['Arman Bostani']
7
13
  gem.email = ['arman.bostani@pnmac.com']
@@ -9,7 +15,7 @@ Gem::Specification.new do |gem|
9
15
  gem.summary = 'Delorean compiler'
10
16
  gem.homepage = 'https://github.com/arman000/delorean_lang'
11
17
 
12
- gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
18
+ gem.files = files
13
19
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
14
20
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
21
  gem.name = 'delorean_lang'
@@ -6,6 +6,7 @@ require 'bigdecimal'
6
6
  require 'delorean/ruby'
7
7
  require 'delorean/ruby/whitelists/default'
8
8
  require 'delorean/cache'
9
+ require 'delorean/const'
9
10
 
10
11
  module Delorean
11
12
  ::Delorean::Ruby.whitelist = ::Delorean::Ruby::Whitelists::Default.new
@@ -16,6 +17,12 @@ module Delorean
16
17
 
17
18
  ::Delorean::Ruby.error_handler = ::Delorean::Ruby::DEFAULT_ERROR_HANDLER
18
19
 
20
+ cache_callback = ::Delorean::Cache::NODE_CACHE_DEFAULT_CALLBACK
21
+
22
+ ::Delorean::Cache.node_cache_callback = cache_callback
23
+
24
+ NODE_CACHE_ARG = "_cache#{POST}".to_sym
25
+
19
26
  module BaseModule
20
27
  # _e is used by Marty promise_jobs to pass promise-related
21
28
  # information
@@ -29,9 +36,24 @@ module Delorean
29
36
  end
30
37
 
31
38
  def evaluate(attr)
39
+ if node.respond_to?(NODE_CACHE_ARG) && node.send(NODE_CACHE_ARG, _e)
40
+ return _evaluate_with_cache(attr)
41
+ end
42
+
32
43
  engine.evaluate(node, attr, cloned_params)
33
44
  end
34
45
 
46
+ def _evaluate_with_cache(attr)
47
+ ::Delorean::Cache.with_cache(
48
+ klass: node,
49
+ method: attr,
50
+ mutable_params: cloned_params,
51
+ params: params
52
+ ) do
53
+ engine.evaluate(node, attr, cloned_params)
54
+ end
55
+ end
56
+
35
57
  def /(args)
36
58
  case args
37
59
  when Array
@@ -85,7 +107,7 @@ module Delorean
85
107
  end
86
108
 
87
109
  begin
88
- return _instance_call(obj, attr, [], _e)
110
+ _instance_call(obj, attr, [], _e)
89
111
  rescue StandardError => exc
90
112
  raise(
91
113
  InvalidGetAttribute,
@@ -111,9 +133,9 @@ module Delorean
111
133
  return nil unless obj.respond_to?(attr)
112
134
 
113
135
  begin
114
- return _instance_call(obj, attr, [], _e)
136
+ _instance_call(obj, attr, [], _e)
115
137
  rescue StandardError
116
- return nil
138
+ nil
117
139
  end
118
140
  end
119
141
 
@@ -4,12 +4,50 @@ require 'delorean/cache/adapters'
4
4
 
5
5
  module Delorean
6
6
  module Cache
7
- def self.adapter
8
- @adapter
7
+ NODE_CACHE_DEFAULT_CALLBACK = lambda do |klass:, method:, params:|
8
+ {
9
+ cache: true,
10
+ }
9
11
  end
10
12
 
11
- def self.adapter=(new_adapter)
12
- @adapter = new_adapter
13
+ class << self
14
+ attr_accessor :adapter
15
+
16
+ def with_cache(klass:, method:, mutable_params:, params:)
17
+ delorean_cache_adapter = ::Delorean::Cache.adapter
18
+
19
+ klass_name = "#{klass.name}#{::Delorean::POST}"
20
+
21
+ cache_options = node_cache_callback.call(
22
+ klass: klass,
23
+ method: method,
24
+ params: mutable_params
25
+ )
26
+
27
+ return yield unless cache_options[:cache]
28
+
29
+ cache_key = delorean_cache_adapter.cache_key(
30
+ klass: klass_name, method_name: method, args: [params]
31
+ )
32
+
33
+ cached_item = delorean_cache_adapter.fetch_item(
34
+ klass: klass_name, cache_key: cache_key, default: :NF
35
+ )
36
+
37
+ return cached_item if cached_item != :NF
38
+
39
+ res = yield
40
+
41
+ delorean_cache_adapter.cache_item(
42
+ klass: klass_name,
43
+ cache_key: cache_key,
44
+ item: res,
45
+ )
46
+
47
+ res
48
+ end
49
+
50
+ attr_accessor :node_cache_callback
13
51
  end
14
52
  end
15
53
  end
@@ -807,6 +807,104 @@ module Delorean
807
807
  r0
808
808
  end
809
809
 
810
+ module Elsif0
811
+ def v
812
+ elements[2]
813
+ end
814
+
815
+ def e1
816
+ elements[6]
817
+ end
818
+
819
+ end
820
+
821
+ def _nt_elsif
822
+ start_index = index
823
+ if node_cache[:elsif].has_key?(index)
824
+ cached = node_cache[:elsif][index]
825
+ if cached
826
+ node_cache[:elsif][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
827
+ @index = cached.interval.end
828
+ end
829
+ return cached
830
+ end
831
+
832
+ i0, s0 = index, []
833
+ if (match_len = has_terminal?('elsif', false, index))
834
+ r1 = instantiate_node(SyntaxNode,input, index...(index + match_len))
835
+ @index += match_len
836
+ else
837
+ terminal_parse_failure('\'elsif\'')
838
+ r1 = nil
839
+ end
840
+ s0 << r1
841
+ if r1
842
+ r3 = _nt_sp
843
+ if r3
844
+ r2 = r3
845
+ else
846
+ r2 = instantiate_node(SyntaxNode,input, index...index)
847
+ end
848
+ s0 << r2
849
+ if r2
850
+ r4 = _nt_expression
851
+ s0 << r4
852
+ if r4
853
+ r6 = _nt_sp
854
+ if r6
855
+ r5 = r6
856
+ else
857
+ r5 = instantiate_node(SyntaxNode,input, index...index)
858
+ end
859
+ s0 << r5
860
+ if r5
861
+ if (match_len = has_terminal?('then', false, index))
862
+ r7 = instantiate_node(SyntaxNode,input, index...(index + match_len))
863
+ @index += match_len
864
+ else
865
+ terminal_parse_failure('\'then\'')
866
+ r7 = nil
867
+ end
868
+ s0 << r7
869
+ if r7
870
+ r9 = _nt_sp
871
+ if r9
872
+ r8 = r9
873
+ else
874
+ r8 = instantiate_node(SyntaxNode,input, index...index)
875
+ end
876
+ s0 << r8
877
+ if r8
878
+ r10 = _nt_expression
879
+ s0 << r10
880
+ if r10
881
+ r12 = _nt_sp
882
+ if r12
883
+ r11 = r12
884
+ else
885
+ r11 = instantiate_node(SyntaxNode,input, index...index)
886
+ end
887
+ s0 << r11
888
+ end
889
+ end
890
+ end
891
+ end
892
+ end
893
+ end
894
+ end
895
+ if s0.last
896
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
897
+ r0.extend(Elsif0)
898
+ else
899
+ @index = i0
900
+ r0 = nil
901
+ end
902
+
903
+ node_cache[:elsif][start_index] = r0
904
+
905
+ r0
906
+ end
907
+
810
908
  module Expression0
811
909
  def args
812
910
  elements[2]
@@ -839,6 +937,24 @@ module Delorean
839
937
  end
840
938
 
841
939
  module Expression3
940
+ def v
941
+ elements[2]
942
+ end
943
+
944
+ def e1
945
+ elements[6]
946
+ end
947
+
948
+ def elsifs
949
+ elements[9]
950
+ end
951
+
952
+ def e2
953
+ elements[13]
954
+ end
955
+ end
956
+
957
+ module Expression4
842
958
  def v
843
959
  elements[0]
844
960
  end
@@ -1046,7 +1162,13 @@ module Delorean
1046
1162
  r0 = r15
1047
1163
  else
1048
1164
  i32, s32 = index, []
1049
- r33 = _nt_getattr_exp
1165
+ if (match_len = has_terminal?('if', false, index))
1166
+ r33 = instantiate_node(SyntaxNode,input, index...(index + match_len))
1167
+ @index += match_len
1168
+ else
1169
+ terminal_parse_failure('\'if\'')
1170
+ r33 = nil
1171
+ end
1050
1172
  s32 << r33
1051
1173
  if r33
1052
1174
  r35 = _nt_sp
@@ -1057,7 +1179,7 @@ module Delorean
1057
1179
  end
1058
1180
  s32 << r34
1059
1181
  if r34
1060
- r36 = _nt_binary_op
1182
+ r36 = _nt_expression
1061
1183
  s32 << r36
1062
1184
  if r36
1063
1185
  r38 = _nt_sp
@@ -1068,14 +1190,101 @@ module Delorean
1068
1190
  end
1069
1191
  s32 << r37
1070
1192
  if r37
1071
- r39 = _nt_expression
1193
+ if (match_len = has_terminal?('then', false, index))
1194
+ r39 = instantiate_node(SyntaxNode,input, index...(index + match_len))
1195
+ @index += match_len
1196
+ else
1197
+ terminal_parse_failure('\'then\'')
1198
+ r39 = nil
1199
+ end
1072
1200
  s32 << r39
1201
+ if r39
1202
+ r41 = _nt_sp
1203
+ if r41
1204
+ r40 = r41
1205
+ else
1206
+ r40 = instantiate_node(SyntaxNode,input, index...index)
1207
+ end
1208
+ s32 << r40
1209
+ if r40
1210
+ r42 = _nt_expression
1211
+ s32 << r42
1212
+ if r42
1213
+ r44 = _nt_sp
1214
+ if r44
1215
+ r43 = r44
1216
+ else
1217
+ r43 = instantiate_node(SyntaxNode,input, index...index)
1218
+ end
1219
+ s32 << r43
1220
+ if r43
1221
+ r46 = _nt_sp
1222
+ if r46
1223
+ r45 = r46
1224
+ else
1225
+ r45 = instantiate_node(SyntaxNode,input, index...index)
1226
+ end
1227
+ s32 << r45
1228
+ if r45
1229
+ s47, i47 = [], index
1230
+ loop do
1231
+ r48 = _nt_elsif
1232
+ if r48
1233
+ s47 << r48
1234
+ else
1235
+ break
1236
+ end
1237
+ end
1238
+ if s47.empty?
1239
+ @index = i47
1240
+ r47 = nil
1241
+ else
1242
+ r47 = instantiate_node(SyntaxNode,input, i47...index, s47)
1243
+ end
1244
+ s32 << r47
1245
+ if r47
1246
+ r50 = _nt_sp
1247
+ if r50
1248
+ r49 = r50
1249
+ else
1250
+ r49 = instantiate_node(SyntaxNode,input, index...index)
1251
+ end
1252
+ s32 << r49
1253
+ if r49
1254
+ if (match_len = has_terminal?('else', false, index))
1255
+ r51 = instantiate_node(SyntaxNode,input, index...(index + match_len))
1256
+ @index += match_len
1257
+ else
1258
+ terminal_parse_failure('\'else\'')
1259
+ r51 = nil
1260
+ end
1261
+ s32 << r51
1262
+ if r51
1263
+ r53 = _nt_sp
1264
+ if r53
1265
+ r52 = r53
1266
+ else
1267
+ r52 = instantiate_node(SyntaxNode,input, index...index)
1268
+ end
1269
+ s32 << r52
1270
+ if r52
1271
+ r54 = _nt_expression
1272
+ s32 << r54
1273
+ end
1274
+ end
1275
+ end
1276
+ end
1277
+ end
1278
+ end
1279
+ end
1280
+ end
1281
+ end
1073
1282
  end
1074
1283
  end
1075
1284
  end
1076
1285
  end
1077
1286
  if s32.last
1078
- r32 = instantiate_node(BinOp,input, i32...index, s32)
1287
+ r32 = instantiate_node(IfElsifElse,input, i32...index, s32)
1079
1288
  r32.extend(Expression3)
1080
1289
  else
1081
1290
  @index = i32
@@ -1085,13 +1294,54 @@ module Delorean
1085
1294
  r32 = SyntaxNode.new(input, (index-1)...index) if r32 == true
1086
1295
  r0 = r32
1087
1296
  else
1088
- r40 = _nt_getattr_exp
1089
- if r40
1090
- r40 = SyntaxNode.new(input, (index-1)...index) if r40 == true
1091
- r0 = r40
1297
+ i55, s55 = index, []
1298
+ r56 = _nt_getattr_exp
1299
+ s55 << r56
1300
+ if r56
1301
+ r58 = _nt_sp
1302
+ if r58
1303
+ r57 = r58
1304
+ else
1305
+ r57 = instantiate_node(SyntaxNode,input, index...index)
1306
+ end
1307
+ s55 << r57
1308
+ if r57
1309
+ r59 = _nt_binary_op
1310
+ s55 << r59
1311
+ if r59
1312
+ r61 = _nt_sp
1313
+ if r61
1314
+ r60 = r61
1315
+ else
1316
+ r60 = instantiate_node(SyntaxNode,input, index...index)
1317
+ end
1318
+ s55 << r60
1319
+ if r60
1320
+ r62 = _nt_expression
1321
+ s55 << r62
1322
+ end
1323
+ end
1324
+ end
1325
+ end
1326
+ if s55.last
1327
+ r55 = instantiate_node(BinOp,input, i55...index, s55)
1328
+ r55.extend(Expression4)
1092
1329
  else
1093
- @index = i0
1094
- r0 = nil
1330
+ @index = i55
1331
+ r55 = nil
1332
+ end
1333
+ if r55
1334
+ r55 = SyntaxNode.new(input, (index-1)...index) if r55 == true
1335
+ r0 = r55
1336
+ else
1337
+ r63 = _nt_getattr_exp
1338
+ if r63
1339
+ r63 = SyntaxNode.new(input, (index-1)...index) if r63 == true
1340
+ r0 = r63
1341
+ else
1342
+ @index = i0
1343
+ r0 = nil
1344
+ end
1095
1345
  end
1096
1346
  end
1097
1347
  end
@@ -3290,12 +3540,12 @@ module Delorean
3290
3540
  r5 = SyntaxNode.new(input, (index-1)...index) if r5 == true
3291
3541
  r0 = r5
3292
3542
  else
3293
- r6 = _nt_identifier
3543
+ r6 = _nt_sup
3294
3544
  if r6
3295
3545
  r6 = SyntaxNode.new(input, (index-1)...index) if r6 == true
3296
3546
  r0 = r6
3297
3547
  else
3298
- r7 = _nt_sup
3548
+ r7 = _nt_identifier
3299
3549
  if r7
3300
3550
  r7 = SyntaxNode.new(input, (index-1)...index) if r7 == true
3301
3551
  r0 = r7
@@ -4439,6 +4689,9 @@ module Delorean
4439
4689
  module Identifier0
4440
4690
  end
4441
4691
 
4692
+ module Identifier1
4693
+ end
4694
+
4442
4695
  def _nt_identifier
4443
4696
  start_index = index
4444
4697
  if node_cache[:identifier].has_key?(index)
@@ -4450,55 +4703,123 @@ module Delorean
4450
4703
  return cached
4451
4704
  end
4452
4705
 
4453
- i0, s0 = index, []
4706
+ i0 = index
4707
+ i1, s1 = index, []
4454
4708
  if has_terminal?(@regexps[gr = '\A[a-z]'] ||= Regexp.new(gr), :regexp, index)
4455
- r1 = true
4709
+ r2 = true
4456
4710
  @index += 1
4457
4711
  else
4458
4712
  terminal_parse_failure('[a-z]')
4459
- r1 = nil
4713
+ r2 = nil
4460
4714
  end
4461
- s0 << r1
4462
- if r1
4463
- s2, i2 = [], index
4715
+ s1 << r2
4716
+ if r2
4717
+ s3, i3 = [], index
4464
4718
  loop do
4465
4719
  if has_terminal?(@regexps[gr = '\A[a-zA-Z0-9_]'] ||= Regexp.new(gr), :regexp, index)
4466
- r3 = true
4720
+ r4 = true
4467
4721
  @index += 1
4468
4722
  else
4469
4723
  terminal_parse_failure('[a-zA-Z0-9_]')
4470
- r3 = nil
4724
+ r4 = nil
4471
4725
  end
4472
- if r3
4473
- s2 << r3
4726
+ if r4
4727
+ s3 << r4
4474
4728
  else
4475
4729
  break
4476
4730
  end
4477
4731
  end
4478
- r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
4479
- s0 << r2
4480
- if r2
4732
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
4733
+ s1 << r3
4734
+ if r3
4481
4735
  if (match_len = has_terminal?('?', false, index))
4482
- r5 = true
4736
+ r6 = true
4483
4737
  @index += match_len
4484
4738
  else
4485
4739
  terminal_parse_failure('\'?\'')
4486
- r5 = nil
4740
+ r6 = nil
4487
4741
  end
4488
- if r5
4489
- r4 = r5
4742
+ if r6
4743
+ r5 = r6
4490
4744
  else
4491
- r4 = instantiate_node(SyntaxNode,input, index...index)
4745
+ r5 = instantiate_node(SyntaxNode,input, index...index)
4492
4746
  end
4493
- s0 << r4
4747
+ s1 << r5
4494
4748
  end
4495
4749
  end
4496
- if s0.last
4497
- r0 = instantiate_node(Identifier,input, i0...index, s0)
4498
- r0.extend(Identifier0)
4750
+ if s1.last
4751
+ r1 = instantiate_node(Identifier,input, i1...index, s1)
4752
+ r1.extend(Identifier0)
4499
4753
  else
4500
- @index = i0
4501
- r0 = nil
4754
+ @index = i1
4755
+ r1 = nil
4756
+ end
4757
+ if r1
4758
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
4759
+ r0 = r1
4760
+ else
4761
+ i7, s7 = index, []
4762
+ if has_terminal?(@regexps[gr = '\A[_]'] ||= Regexp.new(gr), :regexp, index)
4763
+ r8 = true
4764
+ @index += 1
4765
+ else
4766
+ terminal_parse_failure('[_]')
4767
+ r8 = nil
4768
+ end
4769
+ s7 << r8
4770
+ if r8
4771
+ s9, i9 = [], index
4772
+ loop do
4773
+ if has_terminal?(@regexps[gr = '\A[a-zA-Z0-9_]'] ||= Regexp.new(gr), :regexp, index)
4774
+ r10 = true
4775
+ @index += 1
4776
+ else
4777
+ terminal_parse_failure('[a-zA-Z0-9_]')
4778
+ r10 = nil
4779
+ end
4780
+ if r10
4781
+ s9 << r10
4782
+ else
4783
+ break
4784
+ end
4785
+ end
4786
+ if s9.empty?
4787
+ @index = i9
4788
+ r9 = nil
4789
+ else
4790
+ r9 = instantiate_node(SyntaxNode,input, i9...index, s9)
4791
+ end
4792
+ s7 << r9
4793
+ if r9
4794
+ if (match_len = has_terminal?('?', false, index))
4795
+ r12 = true
4796
+ @index += match_len
4797
+ else
4798
+ terminal_parse_failure('\'?\'')
4799
+ r12 = nil
4800
+ end
4801
+ if r12
4802
+ r11 = r12
4803
+ else
4804
+ r11 = instantiate_node(SyntaxNode,input, index...index)
4805
+ end
4806
+ s7 << r11
4807
+ end
4808
+ end
4809
+ if s7.last
4810
+ r7 = instantiate_node(Identifier,input, i7...index, s7)
4811
+ r7.extend(Identifier1)
4812
+ else
4813
+ @index = i7
4814
+ r7 = nil
4815
+ end
4816
+ if r7
4817
+ r7 = SyntaxNode.new(input, (index-1)...index) if r7 == true
4818
+ r0 = r7
4819
+ else
4820
+ @index = i0
4821
+ r0 = nil
4822
+ end
4502
4823
  end
4503
4824
 
4504
4825
  node_cache[:identifier][start_index] = r0