delorean_lang 2.1.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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