delorean_lang 0.2.0 → 0.2.1
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 +8 -8
- data/lib/delorean/delorean.rb +83 -50
- data/lib/delorean/delorean.treetop +21 -16
- data/lib/delorean/error.rb +4 -0
- data/lib/delorean/version.rb +1 -1
- data/spec/dev_spec.rb +29 -29
- data/spec/eval_spec.rb +181 -181
- data/spec/func_spec.rb +41 -41
- data/spec/parse_spec.rb +142 -142
- metadata +2 -2
data/spec/func_spec.rb
CHANGED
@@ -8,7 +8,7 @@ describe "Delorean" do
|
|
8
8
|
|
9
9
|
it "should handle MAX as a node name" do
|
10
10
|
engine.parse defn("MAX:",
|
11
|
-
"
|
11
|
+
" a = [1, 2, 3, 0, -10].max()",
|
12
12
|
)
|
13
13
|
|
14
14
|
r = engine.evaluate("MAX", "a")
|
@@ -17,7 +17,7 @@ describe "Delorean" do
|
|
17
17
|
|
18
18
|
it "should handle MIN" do
|
19
19
|
engine.parse defn("A:",
|
20
|
-
"
|
20
|
+
" a = [1, 2, -3, 4].min()",
|
21
21
|
)
|
22
22
|
|
23
23
|
r = engine.evaluate("A", "a")
|
@@ -26,9 +26,9 @@ describe "Delorean" do
|
|
26
26
|
|
27
27
|
it "should handle ROUND" do
|
28
28
|
engine.parse defn("A:",
|
29
|
-
"
|
30
|
-
"
|
31
|
-
"
|
29
|
+
" a = 12.3456.round(2)",
|
30
|
+
" b = 12.3456.round(1)",
|
31
|
+
" c = 12.3456.round()",
|
32
32
|
)
|
33
33
|
|
34
34
|
r = engine.evaluate_attrs("A", ["a", "b", "c"])
|
@@ -37,9 +37,9 @@ describe "Delorean" do
|
|
37
37
|
|
38
38
|
it "should handle NUMBER" do
|
39
39
|
engine.parse defn("A:",
|
40
|
-
"
|
41
|
-
"
|
42
|
-
"
|
40
|
+
" a = 12.3456.to_f()",
|
41
|
+
" b = '12.3456'.to_f()",
|
42
|
+
" c = '12'.to_f()",
|
43
43
|
)
|
44
44
|
|
45
45
|
r = engine.evaluate_attrs("A", ["a", "b", "c"])
|
@@ -48,10 +48,10 @@ describe "Delorean" do
|
|
48
48
|
|
49
49
|
it "should handle ABS" do
|
50
50
|
engine.parse defn("A:",
|
51
|
-
"
|
52
|
-
"
|
53
|
-
"
|
54
|
-
"
|
51
|
+
" a = (-123).abs()",
|
52
|
+
" b = (-1.1).abs()",
|
53
|
+
" c = 2.3.abs()",
|
54
|
+
" d = 0.abs()",
|
55
55
|
)
|
56
56
|
|
57
57
|
r = engine.evaluate_attrs("A", ["a", "b", "c", "d"])
|
@@ -60,9 +60,9 @@ describe "Delorean" do
|
|
60
60
|
|
61
61
|
it "should handle STRING" do
|
62
62
|
engine.parse defn("A:",
|
63
|
-
"
|
64
|
-
"
|
65
|
-
"
|
63
|
+
" a = 'hello'.to_s()",
|
64
|
+
" b = 12.3456.to_s()",
|
65
|
+
" c = [1,2,3].to_s()",
|
66
66
|
)
|
67
67
|
|
68
68
|
r = engine.evaluate_attrs("A", ["a", "b", "c"])
|
@@ -71,11 +71,11 @@ describe "Delorean" do
|
|
71
71
|
|
72
72
|
it "should handle TIMEPART" do
|
73
73
|
engine.parse defn("A:",
|
74
|
-
"
|
75
|
-
"
|
76
|
-
"
|
77
|
-
"
|
78
|
-
"
|
74
|
+
" p =?",
|
75
|
+
" h = p.hour()",
|
76
|
+
" m = p.min()",
|
77
|
+
" s = p.sec()",
|
78
|
+
" d = p.to_date()",
|
79
79
|
)
|
80
80
|
|
81
81
|
p = Time.now
|
@@ -90,10 +90,10 @@ describe "Delorean" do
|
|
90
90
|
|
91
91
|
it "should handle DATEPART" do
|
92
92
|
engine.parse defn("A:",
|
93
|
-
"
|
94
|
-
"
|
95
|
-
"
|
96
|
-
"
|
93
|
+
" p =?",
|
94
|
+
" y = p.year()",
|
95
|
+
" d = p.day()",
|
96
|
+
" m = p.month()",
|
97
97
|
)
|
98
98
|
|
99
99
|
p = Date.today
|
@@ -108,8 +108,8 @@ describe "Delorean" do
|
|
108
108
|
x = [[1,2,[3]], 4, 5, [6]]
|
109
109
|
|
110
110
|
engine.parse defn("A:",
|
111
|
-
"
|
112
|
-
"
|
111
|
+
" a = #{x}",
|
112
|
+
" b = a.flatten() + a.flatten(1)"
|
113
113
|
)
|
114
114
|
|
115
115
|
engine.evaluate("A", "b").should == x.flatten + x.flatten(1)
|
@@ -117,8 +117,8 @@ describe "Delorean" do
|
|
117
117
|
|
118
118
|
it "should handle ERR" do
|
119
119
|
engine.parse defn("A:",
|
120
|
-
"
|
121
|
-
"
|
120
|
+
" a = ERR('hello')",
|
121
|
+
" b = ERR('xx', 1, 2, 3)",
|
122
122
|
)
|
123
123
|
|
124
124
|
expect { engine.evaluate("A", "a") }.to raise_error('hello')
|
@@ -132,17 +132,17 @@ describe "Delorean" do
|
|
132
132
|
x = [[1, 2, [-3]], 4, 5, [6], -3, 4, 5, 0]
|
133
133
|
|
134
134
|
engine.parse defn("A:",
|
135
|
-
"
|
136
|
-
"
|
137
|
-
"
|
138
|
-
"
|
139
|
-
"
|
140
|
-
"
|
141
|
-
"
|
142
|
-
"
|
143
|
-
"
|
144
|
-
"
|
145
|
-
"
|
135
|
+
" a = #{x}",
|
136
|
+
" b = a.flatten()",
|
137
|
+
" c = a.flatten(1)",
|
138
|
+
" d = b+c",
|
139
|
+
" dd = d.flatten()",
|
140
|
+
" e = dd.sort()",
|
141
|
+
" f = e.uniq()",
|
142
|
+
" g = e.length()",
|
143
|
+
" gg = a.length()",
|
144
|
+
" l = a.member(5)",
|
145
|
+
" m = [a.member(5), a.member(55)]",
|
146
146
|
)
|
147
147
|
|
148
148
|
engine.evaluate("A", "c").should == x.flatten(1)
|
@@ -159,8 +159,8 @@ describe "Delorean" do
|
|
159
159
|
x = [[1, 2, [-3]], 4, [5, 6], -3, 4, 5, 0]
|
160
160
|
|
161
161
|
engine.parse defn("A:",
|
162
|
-
"
|
163
|
-
"
|
162
|
+
" a = #{x}",
|
163
|
+
" b = a.slice(0, 4)",
|
164
164
|
)
|
165
165
|
engine.evaluate("A", "b").should == x.slice(0,4)
|
166
166
|
end
|
data/spec/parse_spec.rb
CHANGED
@@ -6,8 +6,8 @@ describe "Delorean" do
|
|
6
6
|
TestContainer.new({
|
7
7
|
"AAA" =>
|
8
8
|
defn("X:",
|
9
|
-
"
|
10
|
-
"
|
9
|
+
" a = 123",
|
10
|
+
" b = a",
|
11
11
|
)
|
12
12
|
})
|
13
13
|
}
|
@@ -18,51 +18,51 @@ describe "Delorean" do
|
|
18
18
|
|
19
19
|
it "can parse very simple calls" do
|
20
20
|
engine.parse defn("X:",
|
21
|
-
"
|
22
|
-
"
|
21
|
+
" a = 123",
|
22
|
+
" b = a",
|
23
23
|
)
|
24
24
|
end
|
25
25
|
|
26
26
|
it "can parse simple expressions - 1" do
|
27
27
|
engine.parse defn("A:",
|
28
|
-
"
|
29
|
-
"
|
30
|
-
"
|
28
|
+
" a = 123",
|
29
|
+
" x = -(a*2)",
|
30
|
+
" b = -(a + 1)",
|
31
31
|
)
|
32
32
|
end
|
33
33
|
|
34
34
|
it "can parse simple expressions - 2" do
|
35
35
|
engine.parse defn("A:",
|
36
|
-
"
|
36
|
+
" a = 1 + 2 * -3 - -4",
|
37
37
|
)
|
38
38
|
end
|
39
39
|
|
40
40
|
it "can parse params" do
|
41
41
|
engine.parse defn("A:",
|
42
|
-
"
|
43
|
-
"
|
42
|
+
" a =?",
|
43
|
+
" b =? a*2",
|
44
44
|
)
|
45
45
|
end
|
46
46
|
|
47
47
|
it "can parse indexing" do
|
48
48
|
engine.parse defn("A:",
|
49
|
-
"
|
49
|
+
" b = [1,2,3][1]",
|
50
50
|
)
|
51
51
|
end
|
52
52
|
|
53
53
|
it "can parse indexing with getattr" do
|
54
54
|
engine.parse defn("A:",
|
55
|
-
"
|
56
|
-
"
|
55
|
+
" a = {'x': [1,2,3]}",
|
56
|
+
" b = a.x[1]",
|
57
57
|
)
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should accept default param definitions" do
|
61
61
|
lambda {
|
62
62
|
engine.parse defn("A:",
|
63
|
-
"
|
64
|
-
"
|
65
|
-
"
|
63
|
+
" b =? 1",
|
64
|
+
" c =? -1.1",
|
65
|
+
" d = b + c",
|
66
66
|
)
|
67
67
|
}.should_not raise_error
|
68
68
|
end
|
@@ -78,7 +78,7 @@ describe "Delorean" do
|
|
78
78
|
it "should disallow .<digits> literals" do
|
79
79
|
lambda {
|
80
80
|
engine.parse defn("A:",
|
81
|
-
"
|
81
|
+
" a = .123",
|
82
82
|
)
|
83
83
|
}.should raise_error(Delorean::ParseError)
|
84
84
|
end
|
@@ -86,7 +86,7 @@ describe "Delorean" do
|
|
86
86
|
it "should disallow bad attr names" do
|
87
87
|
lambda {
|
88
88
|
engine.parse defn("A:",
|
89
|
-
"
|
89
|
+
" B = 1",
|
90
90
|
)
|
91
91
|
}.should raise_error(Delorean::ParseError)
|
92
92
|
|
@@ -94,7 +94,7 @@ describe "Delorean" do
|
|
94
94
|
|
95
95
|
lambda {
|
96
96
|
engine.parse defn("A:",
|
97
|
-
"
|
97
|
+
" _b = 1",
|
98
98
|
)
|
99
99
|
}.should raise_error(Delorean::ParseError)
|
100
100
|
end
|
@@ -116,9 +116,9 @@ describe "Delorean" do
|
|
116
116
|
it "should disallow recursion" do
|
117
117
|
lambda {
|
118
118
|
engine.parse defn("A:",
|
119
|
-
"
|
119
|
+
" a = 1",
|
120
120
|
"B: A",
|
121
|
-
"
|
121
|
+
" a = a + 1",
|
122
122
|
)
|
123
123
|
}.should raise_error(Delorean::RecursionError)
|
124
124
|
|
@@ -126,10 +126,10 @@ describe "Delorean" do
|
|
126
126
|
|
127
127
|
lambda {
|
128
128
|
engine.parse defn("A:",
|
129
|
-
"
|
129
|
+
" a = 1",
|
130
130
|
"B: A",
|
131
|
-
"
|
132
|
-
"
|
131
|
+
" b = a",
|
132
|
+
" a = b",
|
133
133
|
)
|
134
134
|
}.should raise_error(Delorean::RecursionError)
|
135
135
|
|
@@ -137,45 +137,45 @@ describe "Delorean" do
|
|
137
137
|
|
138
138
|
it "should allow getattr in expressions" do
|
139
139
|
engine.parse defn("A:",
|
140
|
-
"
|
141
|
-
"
|
140
|
+
" a = 1",
|
141
|
+
" b = A.a * A.a - A.a",
|
142
142
|
)
|
143
143
|
end
|
144
144
|
|
145
145
|
it "should allow non-recursive code 1" do
|
146
146
|
# this is not a recursion error
|
147
147
|
engine.parse defn("A:",
|
148
|
-
"
|
149
|
-
"
|
148
|
+
" a = 1",
|
149
|
+
" b = 2",
|
150
150
|
"B: A",
|
151
|
-
"
|
152
|
-
"
|
151
|
+
" a = A.b",
|
152
|
+
" b = a",
|
153
153
|
)
|
154
154
|
|
155
155
|
end
|
156
156
|
|
157
157
|
it "should allow non-recursive code 2" do
|
158
158
|
engine.parse defn("A:",
|
159
|
-
"
|
160
|
-
"
|
159
|
+
" a = 1",
|
160
|
+
" b = 2",
|
161
161
|
"B: A",
|
162
|
-
"
|
163
|
-
"
|
162
|
+
" a = A.b",
|
163
|
+
" b = A.b + B.a",
|
164
164
|
)
|
165
165
|
end
|
166
166
|
|
167
167
|
it "should allow non-recursive code 3" do
|
168
168
|
engine.parse defn("A:",
|
169
|
-
"
|
170
|
-
"
|
171
|
-
"
|
169
|
+
" b = 2",
|
170
|
+
" a = A.b + A.b",
|
171
|
+
" c = a + b + a + b",
|
172
172
|
)
|
173
173
|
end
|
174
174
|
|
175
175
|
it "should check for recursion with default params 1" do
|
176
176
|
lambda {
|
177
177
|
engine.parse defn("A:",
|
178
|
-
"
|
178
|
+
" a =? a",
|
179
179
|
)
|
180
180
|
}.should raise_error(Delorean::UndefinedError)
|
181
181
|
end
|
@@ -183,10 +183,10 @@ describe "Delorean" do
|
|
183
183
|
it "should check for recursion with default params 2" do
|
184
184
|
lambda {
|
185
185
|
engine.parse defn("A:",
|
186
|
-
"
|
186
|
+
" a = 1",
|
187
187
|
"B: A",
|
188
|
-
"
|
189
|
-
"
|
188
|
+
" b =? a",
|
189
|
+
" a =? b",
|
190
190
|
)
|
191
191
|
}.should raise_error(Delorean::RecursionError)
|
192
192
|
end
|
@@ -194,8 +194,8 @@ describe "Delorean" do
|
|
194
194
|
it "gives errors for attrs defined more than once in a node" do
|
195
195
|
lambda {
|
196
196
|
engine.parse defn("B:",
|
197
|
-
"
|
198
|
-
"
|
197
|
+
" b = 1 + 1",
|
198
|
+
" b = 123",
|
199
199
|
)
|
200
200
|
}.should raise_error(Delorean::RedefinedError)
|
201
201
|
|
@@ -203,8 +203,8 @@ describe "Delorean" do
|
|
203
203
|
|
204
204
|
lambda {
|
205
205
|
engine.parse defn("B:",
|
206
|
-
"
|
207
|
-
"
|
206
|
+
" b =?",
|
207
|
+
" b = 123",
|
208
208
|
)
|
209
209
|
}.should raise_error(Delorean::RedefinedError)
|
210
210
|
|
@@ -212,8 +212,8 @@ describe "Delorean" do
|
|
212
212
|
|
213
213
|
lambda {
|
214
214
|
engine.parse defn("B:",
|
215
|
-
"
|
216
|
-
"
|
215
|
+
" b =? 22",
|
216
|
+
" b = 123",
|
217
217
|
)
|
218
218
|
}.should raise_error(Delorean::RedefinedError)
|
219
219
|
end
|
@@ -221,7 +221,7 @@ describe "Delorean" do
|
|
221
221
|
it "should raise error for nodes defined more than once" do
|
222
222
|
lambda {
|
223
223
|
engine.parse defn("B:",
|
224
|
-
"
|
224
|
+
" b =?",
|
225
225
|
"B:",
|
226
226
|
)
|
227
227
|
}.should raise_error(Delorean::RedefinedError)
|
@@ -239,7 +239,7 @@ describe "Delorean" do
|
|
239
239
|
it "should not be valid to derive from undefined nodes" do
|
240
240
|
lambda {
|
241
241
|
engine.parse defn("A: B",
|
242
|
-
"
|
242
|
+
" a = 456 * 123",
|
243
243
|
)
|
244
244
|
}.should raise_error(Delorean::UndefinedError)
|
245
245
|
end
|
@@ -247,10 +247,10 @@ describe "Delorean" do
|
|
247
247
|
it "should not be valid to use an undefined attr" do
|
248
248
|
lambda {
|
249
249
|
engine.parse defn("A:",
|
250
|
-
"
|
250
|
+
" a = 456 * 123",
|
251
251
|
"B: A",
|
252
|
-
"
|
253
|
-
"
|
252
|
+
" b = a",
|
253
|
+
" c = d",
|
254
254
|
)
|
255
255
|
}.should raise_error(Delorean::UndefinedError)
|
256
256
|
end
|
@@ -258,7 +258,7 @@ describe "Delorean" do
|
|
258
258
|
it "should be able to use ruby keywords as identifier" do
|
259
259
|
lambda {
|
260
260
|
engine.parse defn("A:",
|
261
|
-
"
|
261
|
+
" in = 123",
|
262
262
|
)
|
263
263
|
}.should_not raise_error
|
264
264
|
|
@@ -266,7 +266,7 @@ describe "Delorean" do
|
|
266
266
|
|
267
267
|
lambda {
|
268
268
|
engine.parse defn("B:",
|
269
|
-
"
|
269
|
+
" in1 = 123",
|
270
270
|
)
|
271
271
|
}.should_not raise_error
|
272
272
|
|
@@ -274,8 +274,8 @@ describe "Delorean" do
|
|
274
274
|
|
275
275
|
lambda {
|
276
276
|
engine.parse defn("C:",
|
277
|
-
"
|
278
|
-
"
|
277
|
+
" ifx = 123",
|
278
|
+
" elsey = ifx + 1",
|
279
279
|
)
|
280
280
|
}.should_not raise_error
|
281
281
|
|
@@ -283,7 +283,7 @@ describe "Delorean" do
|
|
283
283
|
|
284
284
|
lambda {
|
285
285
|
engine.parse defn("D:",
|
286
|
-
"
|
286
|
+
" true = false",
|
287
287
|
)
|
288
288
|
}.should_not raise_error
|
289
289
|
|
@@ -291,8 +291,8 @@ describe "Delorean" do
|
|
291
291
|
|
292
292
|
lambda {
|
293
293
|
engine.parse defn("E:",
|
294
|
-
"
|
295
|
-
"
|
294
|
+
" a = 1",
|
295
|
+
" return=a",
|
296
296
|
)
|
297
297
|
}.should_not raise_error
|
298
298
|
end
|
@@ -300,8 +300,8 @@ describe "Delorean" do
|
|
300
300
|
it "should parse calls followed by getattr" do
|
301
301
|
lambda {
|
302
302
|
engine.parse defn("A:",
|
303
|
-
"
|
304
|
-
"
|
303
|
+
" a = -1",
|
304
|
+
" b = A().a",
|
305
305
|
)
|
306
306
|
}.should_not raise_error
|
307
307
|
end
|
@@ -309,21 +309,21 @@ describe "Delorean" do
|
|
309
309
|
it "should be able to chain method calls on model functions" do
|
310
310
|
lambda {
|
311
311
|
engine.parse defn("A:",
|
312
|
-
"
|
312
|
+
" b = Dummy.i_just_met_you('CRJ', 123).name"
|
313
313
|
)
|
314
314
|
}.should_not raise_error
|
315
315
|
end
|
316
316
|
|
317
317
|
it "should be able to call class methods on ActiveRecord classes" do
|
318
318
|
engine.parse defn("A:",
|
319
|
-
"
|
319
|
+
" b = Dummy.call_me_maybe()",
|
320
320
|
)
|
321
321
|
end
|
322
322
|
|
323
323
|
it "should get exception on arg count to class method call" do
|
324
324
|
lambda {
|
325
325
|
engine.parse defn("A:",
|
326
|
-
'
|
326
|
+
' b = Dummy.i_just_met_you("CRJ")',
|
327
327
|
)
|
328
328
|
}.should raise_error(Delorean::BadCallError)
|
329
329
|
end
|
@@ -331,77 +331,77 @@ describe "Delorean" do
|
|
331
331
|
it "shouldn't be able to call ActiveRecord methods without signature" do
|
332
332
|
lambda {
|
333
333
|
engine.parse defn("A:",
|
334
|
-
"
|
334
|
+
" b = Dummy.this_is_crazy()",
|
335
335
|
)
|
336
336
|
}.should raise_error(Delorean::UndefinedFunctionError)
|
337
337
|
end
|
338
338
|
|
339
339
|
it "should be able to call class methods on ActiveRecord classes in modules" do
|
340
340
|
engine.parse defn("A:",
|
341
|
-
"
|
341
|
+
" b = M::LittleDummy.heres_my_number(867, 5309)",
|
342
342
|
)
|
343
343
|
end
|
344
344
|
|
345
345
|
it "should be able to override parameters with attribute definitions" do
|
346
346
|
engine.parse defn("A:",
|
347
|
-
"
|
347
|
+
" b =? 22",
|
348
348
|
"B: A",
|
349
|
-
"
|
349
|
+
" b = 123",
|
350
350
|
"C: B",
|
351
|
-
"
|
351
|
+
" b =? 11",
|
352
352
|
)
|
353
353
|
end
|
354
354
|
|
355
355
|
it "should be able to access derived attrs" do
|
356
356
|
engine.parse defn("A:",
|
357
|
-
"
|
357
|
+
" b =? 22",
|
358
358
|
"B: A",
|
359
|
-
"
|
359
|
+
" c = b * 123",
|
360
360
|
"C: B",
|
361
|
-
"
|
361
|
+
" d =? c * b + 11",
|
362
362
|
)
|
363
363
|
end
|
364
364
|
|
365
365
|
it "should not be able to access attrs not defined in ancestors" do
|
366
366
|
lambda {
|
367
367
|
engine.parse defn("A:",
|
368
|
-
"
|
368
|
+
" b =? 22",
|
369
369
|
"B: A",
|
370
|
-
"
|
370
|
+
" c = b * 123",
|
371
371
|
"C: A",
|
372
|
-
"
|
372
|
+
" d =? c * b + 11",
|
373
373
|
)
|
374
374
|
}.should raise_error(Delorean::UndefinedError)
|
375
375
|
end
|
376
376
|
|
377
377
|
it "should be able to access specific node attrs " do
|
378
378
|
engine.parse defn("A:",
|
379
|
-
"
|
380
|
-
"
|
379
|
+
" b = 123",
|
380
|
+
" c = A.b",
|
381
381
|
)
|
382
382
|
|
383
383
|
engine.reset
|
384
384
|
|
385
385
|
engine.parse defn("A:",
|
386
|
-
"
|
386
|
+
" b = 123",
|
387
387
|
"B: A",
|
388
|
-
"
|
389
|
-
"
|
390
|
-
"
|
388
|
+
" b = 111",
|
389
|
+
" c = A.b * 123",
|
390
|
+
" d = B.b",
|
391
391
|
)
|
392
392
|
end
|
393
393
|
|
394
394
|
it "should be able to perform arbitrary getattr" do
|
395
395
|
engine.parse defn("A:",
|
396
|
-
"
|
397
|
-
"
|
396
|
+
" b = 22",
|
397
|
+
" c = b.x.y.z",
|
398
398
|
)
|
399
399
|
|
400
400
|
engine.reset
|
401
401
|
|
402
402
|
lambda {
|
403
403
|
engine.parse defn("B:",
|
404
|
-
"
|
404
|
+
" c = b.x.y.z",
|
405
405
|
)
|
406
406
|
}.should raise_error(Delorean::UndefinedError)
|
407
407
|
|
@@ -409,15 +409,15 @@ describe "Delorean" do
|
|
409
409
|
|
410
410
|
it "should handle lines with comments" do
|
411
411
|
engine.parse defn("A: # kaka",
|
412
|
-
"
|
413
|
-
"
|
412
|
+
" b = 22 # testing #",
|
413
|
+
" c = b",
|
414
414
|
)
|
415
415
|
end
|
416
416
|
|
417
417
|
it "should be able to report error line during parse" do
|
418
418
|
begin
|
419
419
|
engine.parse defn("A:",
|
420
|
-
"
|
420
|
+
" b = 123",
|
421
421
|
"B: .A",
|
422
422
|
)
|
423
423
|
rescue => exc
|
@@ -430,7 +430,7 @@ describe "Delorean" do
|
|
430
430
|
|
431
431
|
begin
|
432
432
|
engine.parse defn("A:",
|
433
|
-
"
|
433
|
+
" b = 3 % b",
|
434
434
|
)
|
435
435
|
rescue => exc
|
436
436
|
end
|
@@ -450,7 +450,7 @@ describe "Delorean" do
|
|
450
450
|
it "should not allow inherited ruby methods as attrs" do
|
451
451
|
lambda {
|
452
452
|
engine.parse defn("A:",
|
453
|
-
"
|
453
|
+
" a = name",
|
454
454
|
)
|
455
455
|
}.should raise_error(Delorean::UndefinedError)
|
456
456
|
|
@@ -458,24 +458,24 @@ describe "Delorean" do
|
|
458
458
|
|
459
459
|
lambda {
|
460
460
|
engine.parse defn("A:",
|
461
|
-
"
|
461
|
+
" a = new",
|
462
462
|
)
|
463
463
|
}.should raise_error(Delorean::UndefinedError)
|
464
464
|
end
|
465
465
|
|
466
466
|
it "should be able to parse lists" do
|
467
467
|
engine.parse defn("A:",
|
468
|
-
"
|
469
|
-
"
|
470
|
-
"
|
471
|
-
"
|
468
|
+
" b = []",
|
469
|
+
" c = [1,2,3]",
|
470
|
+
" d = [b, c, b, c, 1, 2, '123', 1.1]",
|
471
|
+
" e = [1, 1+1, 1+1+1]",
|
472
472
|
)
|
473
473
|
|
474
474
|
engine.reset
|
475
475
|
|
476
476
|
lambda {
|
477
477
|
engine.parse defn("A:",
|
478
|
-
"
|
478
|
+
" a = [",
|
479
479
|
)
|
480
480
|
}.should raise_error(Delorean::ParseError)
|
481
481
|
|
@@ -483,7 +483,7 @@ describe "Delorean" do
|
|
483
483
|
|
484
484
|
lambda {
|
485
485
|
engine.parse defn("A:",
|
486
|
-
"
|
486
|
+
" a = []-",
|
487
487
|
)
|
488
488
|
}.should raise_error(Delorean::ParseError)
|
489
489
|
|
@@ -491,14 +491,14 @@ describe "Delorean" do
|
|
491
491
|
|
492
492
|
it "should handle trailing ',' with lists" do
|
493
493
|
engine.parse defn("A:",
|
494
|
-
"
|
494
|
+
" b = [1,2,3,]",
|
495
495
|
)
|
496
496
|
|
497
497
|
engine.reset
|
498
498
|
|
499
499
|
lambda {
|
500
500
|
engine.parse defn("A:",
|
501
|
-
"
|
501
|
+
" a = [,]",
|
502
502
|
)
|
503
503
|
}.should raise_error(Delorean::ParseError)
|
504
504
|
|
@@ -506,23 +506,23 @@ describe "Delorean" do
|
|
506
506
|
|
507
507
|
lambda {
|
508
508
|
engine.parse defn("A:",
|
509
|
-
"
|
509
|
+
" a = [1,2,,]",
|
510
510
|
)
|
511
511
|
}.should raise_error(Delorean::ParseError)
|
512
512
|
end
|
513
513
|
|
514
514
|
it "should be able to parse hashes" do
|
515
515
|
engine.parse defn("A:",
|
516
|
-
"
|
517
|
-
"
|
518
|
-
"
|
516
|
+
" b = {}",
|
517
|
+
" c = {'a':1, 'b': 2, 'c':-3}",
|
518
|
+
" d = [{1:11}, {2: 22}]",
|
519
519
|
)
|
520
520
|
|
521
521
|
engine.reset
|
522
522
|
|
523
523
|
lambda {
|
524
524
|
engine.parse defn("A:",
|
525
|
-
"
|
525
|
+
" a = {",
|
526
526
|
)
|
527
527
|
}.should raise_error(Delorean::ParseError)
|
528
528
|
|
@@ -530,21 +530,21 @@ describe "Delorean" do
|
|
530
530
|
|
531
531
|
lambda {
|
532
532
|
engine.parse defn("A:",
|
533
|
-
"
|
533
|
+
" a = {}+",
|
534
534
|
)
|
535
535
|
}.should raise_error(Delorean::ParseError)
|
536
536
|
end
|
537
537
|
|
538
538
|
it "should handle trailing ',' with hashes" do
|
539
539
|
engine.parse defn("A:",
|
540
|
-
"
|
540
|
+
" b = {-1:1,}",
|
541
541
|
)
|
542
542
|
|
543
543
|
engine.reset
|
544
544
|
|
545
545
|
lambda {
|
546
546
|
engine.parse defn("A:",
|
547
|
-
"
|
547
|
+
" a = {,}",
|
548
548
|
)
|
549
549
|
}.should raise_error(Delorean::ParseError)
|
550
550
|
|
@@ -552,62 +552,62 @@ describe "Delorean" do
|
|
552
552
|
|
553
553
|
lambda {
|
554
554
|
engine.parse defn("A:",
|
555
|
-
"
|
555
|
+
" a = {-1:1,,}",
|
556
556
|
)
|
557
557
|
}.should raise_error(Delorean::ParseError)
|
558
558
|
end
|
559
559
|
|
560
560
|
it "should be able to parse list operations " do
|
561
561
|
engine.parse defn("A:",
|
562
|
-
"
|
562
|
+
" b = [] + []",
|
563
563
|
)
|
564
564
|
end
|
565
565
|
|
566
566
|
it "should parse list comprehension" do
|
567
567
|
engine.parse defn("A:",
|
568
|
-
"
|
568
|
+
" b = [123 for i in 123]",
|
569
569
|
)
|
570
570
|
|
571
571
|
end
|
572
572
|
|
573
573
|
it "should parse list comprehension (2)" do
|
574
574
|
engine.parse defn("A:",
|
575
|
-
"
|
575
|
+
" b = [i+1 for i in [1,2,3]]",
|
576
576
|
)
|
577
577
|
|
578
578
|
end
|
579
579
|
|
580
580
|
it "should parse nested list comprehension" do
|
581
581
|
engine.parse defn("A:",
|
582
|
-
"
|
582
|
+
" b = [[a+c for c in [4,5]] for a in [1,2,3]]",
|
583
583
|
)
|
584
584
|
|
585
585
|
end
|
586
586
|
|
587
587
|
it "should accept list comprehension variable override" do
|
588
588
|
engine.parse defn("A:",
|
589
|
-
"
|
589
|
+
" b = [b+1 for b in [1,2,3]]",
|
590
590
|
)
|
591
591
|
end
|
592
592
|
|
593
593
|
it "should accept list comprehension variable override (2)" do
|
594
594
|
engine.parse defn("A:",
|
595
|
-
"
|
596
|
-
"
|
595
|
+
" a = 1",
|
596
|
+
" b = [a+1 for a in [1,2,3]]",
|
597
597
|
)
|
598
598
|
end
|
599
599
|
|
600
600
|
it "errors out on bad list comprehension" do
|
601
601
|
lambda {
|
602
602
|
engine.parse defn("A:",
|
603
|
-
"
|
603
|
+
" b = [i+1 for x in [1,2,3]]",
|
604
604
|
)
|
605
605
|
}.should raise_error(Delorean::UndefinedError)
|
606
606
|
engine.reset
|
607
607
|
|
608
608
|
lambda {
|
609
609
|
engine.parse defn("A:",
|
610
|
-
"
|
610
|
+
" a = [123 for b in b]",
|
611
611
|
)
|
612
612
|
}.should raise_error(Delorean::UndefinedError)
|
613
613
|
engine.reset
|
@@ -615,7 +615,7 @@ describe "Delorean" do
|
|
615
615
|
# disallow nested comprehension var reuse
|
616
616
|
lambda {
|
617
617
|
engine.parse defn("A:",
|
618
|
-
"
|
618
|
+
" b = [[a+1 for a in [4,5]] for a in [1,2,3]]",
|
619
619
|
)
|
620
620
|
}.should raise_error(Delorean::RedefinedError)
|
621
621
|
engine.reset
|
@@ -623,35 +623,35 @@ describe "Delorean" do
|
|
623
623
|
|
624
624
|
it "should allow nodes as values" do
|
625
625
|
engine.parse defn("A:",
|
626
|
-
"
|
626
|
+
" a = 123",
|
627
627
|
"B:",
|
628
|
-
"
|
628
|
+
" a = A",
|
629
629
|
)
|
630
630
|
end
|
631
631
|
|
632
632
|
it "should parse module calls" do
|
633
633
|
engine.parse defn("A:",
|
634
|
-
"
|
635
|
-
"
|
636
|
-
"
|
637
|
-
"
|
638
|
-
"
|
639
|
-
"
|
640
|
-
"
|
634
|
+
" a = 123",
|
635
|
+
" b = 456 + a",
|
636
|
+
" n = 'A'",
|
637
|
+
" c = nil(x = 123, y = 456)",
|
638
|
+
" d = n(x = 123,",
|
639
|
+
" y = 456,",
|
640
|
+
" )",
|
641
641
|
)
|
642
642
|
end
|
643
643
|
|
644
644
|
it "should parse module calls by node name" do
|
645
645
|
engine.parse defn("A:",
|
646
|
-
"
|
647
|
-
"
|
646
|
+
" a = 123",
|
647
|
+
" d = A()",
|
648
648
|
)
|
649
649
|
end
|
650
650
|
|
651
651
|
it "should not allow positional args to node calls" do
|
652
652
|
begin
|
653
653
|
engine.parse defn("A:",
|
654
|
-
"
|
654
|
+
" d = A(1, 2, 3)",
|
655
655
|
)
|
656
656
|
raise "fail"
|
657
657
|
rescue Delorean::ParseError => exc
|
@@ -661,26 +661,26 @@ describe "Delorean" do
|
|
661
661
|
|
662
662
|
it "should parse instance calls" do
|
663
663
|
engine.parse defn("A:",
|
664
|
-
"
|
664
|
+
" a = [1,2,[4]].flatten(1)",
|
665
665
|
)
|
666
666
|
end
|
667
667
|
|
668
668
|
it "should parse multiline attr defs" do
|
669
669
|
engine.parse defn("A:",
|
670
|
-
"
|
671
|
-
"
|
672
|
-
"
|
673
|
-
"
|
670
|
+
" a = [1,",
|
671
|
+
" 2,",
|
672
|
+
" 3]",
|
673
|
+
" b = 456",
|
674
674
|
)
|
675
675
|
end
|
676
676
|
|
677
677
|
it "should give proper errors on parse multiline attr defs" do
|
678
678
|
begin
|
679
679
|
engine.parse defn("A:",
|
680
|
-
"
|
681
|
-
"
|
682
|
-
"
|
683
|
-
"
|
680
|
+
" a = [1,",
|
681
|
+
" 2,",
|
682
|
+
" 3];",
|
683
|
+
" b = 456",
|
684
684
|
)
|
685
685
|
raise "fail"
|
686
686
|
rescue Delorean::ParseError => exc
|
@@ -691,9 +691,9 @@ describe "Delorean" do
|
|
691
691
|
it "should give proper errors when multiline error falls off the end" do
|
692
692
|
begin
|
693
693
|
engine.parse defn("A:",
|
694
|
-
"
|
695
|
-
"
|
696
|
-
"
|
694
|
+
" x = 123",
|
695
|
+
" a = 1 +",
|
696
|
+
" 2 +",
|
697
697
|
)
|
698
698
|
raise "fail"
|
699
699
|
rescue Delorean::ParseError => exc
|
@@ -704,7 +704,7 @@ describe "Delorean" do
|
|
704
704
|
it "should parse imports" do
|
705
705
|
engine.parse defn("import AAA",
|
706
706
|
"A:",
|
707
|
-
"
|
707
|
+
" b = 456",
|
708
708
|
"B: AAA::X",
|
709
709
|
)
|
710
710
|
end
|