delorean_lang 0.0.34 → 0.0.38
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +2 -2
- data/README.md +8 -6
- data/delorean.gemspec +1 -1
- data/lib/delorean/base.rb +22 -10
- data/lib/delorean/const.rb +5 -0
- data/lib/delorean/delorean.rb +570 -416
- data/lib/delorean/delorean.treetop +35 -47
- data/lib/delorean/engine.rb +42 -25
- data/lib/delorean/functions.rb +53 -45
- data/lib/delorean/model.rb +3 -1
- data/lib/delorean/nodes.rb +68 -28
- data/lib/delorean/version.rb +1 -1
- data/spec/dev_spec.rb +4 -6
- data/spec/eval_spec.rb +114 -10
- data/spec/func_spec.rb +22 -18
- data/spec/parse_spec.rb +21 -0
- metadata +7 -6
data/lib/delorean/version.rb
CHANGED
data/spec/dev_spec.rb
CHANGED
@@ -50,11 +50,10 @@ describe "Delorean" do
|
|
50
50
|
" c =?",
|
51
51
|
" d = 456",
|
52
52
|
)
|
53
|
-
engine.enumerate_attrs_by_node("X").should ==
|
54
|
-
engine.enumerate_attrs_by_node("Y").should ==
|
55
|
-
engine.enumerate_attrs_by_node("Z").should ==
|
56
|
-
engine.enumerate_attrs_by_node("XX").should ==
|
57
|
-
engine.enumerate_attrs_by_node("UNK").should == { }
|
53
|
+
engine.enumerate_attrs_by_node("X").should == ["a", "b"]
|
54
|
+
engine.enumerate_attrs_by_node("Y").should == ["a", "b"]
|
55
|
+
engine.enumerate_attrs_by_node("Z").should == []
|
56
|
+
engine.enumerate_attrs_by_node("XX").should == ["a", "c", "d", "b"]
|
58
57
|
end
|
59
58
|
|
60
59
|
it "can enumerate params" do
|
@@ -93,6 +92,5 @@ describe "Delorean" do
|
|
93
92
|
engine.enumerate_params_by_node("XX").should == Set.new(["a", "c"])
|
94
93
|
engine.enumerate_params_by_node("YY").should == Set.new(["a", "c", "e"])
|
95
94
|
engine.enumerate_params_by_node("Z").should == Set.new([])
|
96
|
-
engine.enumerate_params_by_node("UNK").should == Set.new([])
|
97
95
|
end
|
98
96
|
end
|
data/spec/eval_spec.rb
CHANGED
@@ -40,6 +40,14 @@ describe "Delorean" do
|
|
40
40
|
r.should == -122
|
41
41
|
end
|
42
42
|
|
43
|
+
it "should handle getattr in expressions" do
|
44
|
+
engine.parse defn("A:",
|
45
|
+
" a = {'x':123, 'y':456, 'z':789}",
|
46
|
+
" b = A.a.x * A.a.y - A.a.z",
|
47
|
+
)
|
48
|
+
engine.evaluate_attrs("A", ["b"]).should == [123*456-789]
|
49
|
+
end
|
50
|
+
|
43
51
|
it "should be able to evaluate multiple node attrs" do
|
44
52
|
engine.parse defn("A:",
|
45
53
|
" a =? 123",
|
@@ -270,6 +278,33 @@ describe "Delorean" do
|
|
270
278
|
r.name.should == "hello"
|
271
279
|
end
|
272
280
|
|
281
|
+
it "should be able to get attr on node" do
|
282
|
+
engine.parse defn("A:",
|
283
|
+
" a = 123",
|
284
|
+
" b = A",
|
285
|
+
" c = b.a * 2",
|
286
|
+
)
|
287
|
+
engine.evaluate_attrs("A", %w{a c}).should == [123, 123*2]
|
288
|
+
end
|
289
|
+
|
290
|
+
getattr_code = <<eoc
|
291
|
+
A:
|
292
|
+
x = 1
|
293
|
+
B:
|
294
|
+
x = 2
|
295
|
+
C:
|
296
|
+
x = 3
|
297
|
+
D:
|
298
|
+
xs = [A, B, C]
|
299
|
+
E:
|
300
|
+
xx = [n.x for n in D.xs]
|
301
|
+
eoc
|
302
|
+
|
303
|
+
it "should be able to get attr on node 2" do
|
304
|
+
engine.parse getattr_code
|
305
|
+
engine.evaluate("E", "xx").should == [1,2,3]
|
306
|
+
end
|
307
|
+
|
273
308
|
it "should be able to call class methods on ActiveRecord classes in modules" do
|
274
309
|
engine.parse defn("A:",
|
275
310
|
" b = M::LittleDummy.heres_my_number(867, 5309)",
|
@@ -472,8 +507,10 @@ eof
|
|
472
507
|
it "should eval conditional list comprehension" do
|
473
508
|
engine.parse defn("A:",
|
474
509
|
" b = [i*5 for i in [1,2,3,4,5] if i%2 == 1]",
|
510
|
+
" c = [i/10.0 for i in [1,2,3,4,5] if i>4]",
|
475
511
|
)
|
476
512
|
engine.evaluate("A", "b").should == [5, 15, 25]
|
513
|
+
engine.evaluate("A", "c").should == [0.5]
|
477
514
|
end
|
478
515
|
|
479
516
|
it "should eval hashes" do
|
@@ -496,7 +533,41 @@ eof
|
|
496
533
|
]
|
497
534
|
end
|
498
535
|
|
499
|
-
it "should eval
|
536
|
+
it "should eval hash comprehension" do
|
537
|
+
engine.parse defn("A:",
|
538
|
+
" b = {i*5 :i for i in [1,2,3]}",
|
539
|
+
)
|
540
|
+
engine.evaluate("A", "b").should == {5=>1, 10=>2, 15=>3}
|
541
|
+
end
|
542
|
+
|
543
|
+
it "should eval nested hash comprehension" do
|
544
|
+
engine.parse defn("A:",
|
545
|
+
" b = { a:{a+c:a-c for c in [4,5]} for a in [1,2,3]}",
|
546
|
+
)
|
547
|
+
engine.evaluate("A", "b").should ==
|
548
|
+
{1=>{5=>-3, 6=>-4}, 2=>{6=>-2, 7=>-3}, 3=>{7=>-1, 8=>-2}}
|
549
|
+
end
|
550
|
+
|
551
|
+
it "should eval conditional hash comprehension" do
|
552
|
+
engine.parse defn("A:",
|
553
|
+
" b = {i*5:i+5 for i in [1,2,3,4,5] if i%2 == 1}",
|
554
|
+
" c = {i/10.0:i*10 for i in [1,2,3,4,5] if i>4}",
|
555
|
+
)
|
556
|
+
engine.evaluate("A", "b").should == {5=>6, 15=>8, 25=>10}
|
557
|
+
engine.evaluate("A", "c").should == {0.5=>50}
|
558
|
+
end
|
559
|
+
|
560
|
+
it "should eval module calls 1" do
|
561
|
+
engine.parse defn("A:",
|
562
|
+
" a = 123",
|
563
|
+
" n = A",
|
564
|
+
" d = @n('a')",
|
565
|
+
)
|
566
|
+
|
567
|
+
engine.evaluate_attrs("A", %w{d}).should == [{"a" => 123}]
|
568
|
+
end
|
569
|
+
|
570
|
+
it "should eval module calls 2" do
|
500
571
|
engine.parse defn("A:",
|
501
572
|
" a = 123",
|
502
573
|
" b = 456 + a",
|
@@ -507,16 +578,16 @@ eof
|
|
507
578
|
)
|
508
579
|
|
509
580
|
engine.evaluate_attrs("A", %w{n c d e}).should ==
|
510
|
-
["A", {"a"=>123, "b"=>579}, {"a"=>123, "b"=>579}, 579]
|
581
|
+
["A", {"a"=>123, "b"=>579}, {"a"=>123, "b"=>579}, {"b"=>579}]
|
511
582
|
end
|
512
583
|
|
513
584
|
it "should be possible to implement recursive calls" do
|
514
585
|
engine.parse defn("A:",
|
515
586
|
" n =?",
|
516
|
-
"
|
587
|
+
" fact = if n <= 1 then 1 else n * @('fact', n: n-1).fact",
|
517
588
|
)
|
518
589
|
|
519
|
-
engine.evaluate("A", "
|
590
|
+
engine.evaluate("A", "fact", "n" => 10).should == 3628800
|
520
591
|
end
|
521
592
|
|
522
593
|
it "should eval module calls by node name" do
|
@@ -524,7 +595,7 @@ eof
|
|
524
595
|
" a = 123",
|
525
596
|
" b = @A('a')",
|
526
597
|
)
|
527
|
-
engine.evaluate("A", "b").should == 123
|
598
|
+
engine.evaluate("A", "b").should == {"a"=>123}
|
528
599
|
end
|
529
600
|
|
530
601
|
it "should eval multiline expressions" do
|
@@ -556,7 +627,7 @@ eof
|
|
556
627
|
)
|
557
628
|
|
558
629
|
engine.evaluate_attrs("A", %w{n c d e}).should ==
|
559
|
-
["A", {"a"=>123, "b"=>579}, {"a"=>123, "b"=>579}, 579]
|
630
|
+
["A", {"a"=>123, "b"=>579}, {"a"=>123, "b"=>579}, {"b"=>579}]
|
560
631
|
end
|
561
632
|
|
562
633
|
it "should eval imports" do
|
@@ -567,7 +638,8 @@ eof
|
|
567
638
|
" a = 111",
|
568
639
|
" c = @AAA::X('b', a: 456)",
|
569
640
|
), sset
|
570
|
-
engine.evaluate_attrs("B", ["a", "b", "c"], {}).should ==
|
641
|
+
engine.evaluate_attrs("B", ["a", "b", "c"], {}).should ==
|
642
|
+
[111, 222, {"b"=>456*2}]
|
571
643
|
end
|
572
644
|
|
573
645
|
it "should eval imports (2)" do
|
@@ -591,19 +663,51 @@ eof
|
|
591
663
|
|
592
664
|
e2 = sset.get_engine("BBB", "0002")
|
593
665
|
|
594
|
-
e2.evaluate_attrs("B", ["a", "b", "c", "d"]).should ==
|
666
|
+
e2.evaluate_attrs("B", ["a", "b", "c", "d"]).should ==
|
667
|
+
[111, 222, {"b"=>-2}, 222]
|
595
668
|
|
596
669
|
engine.parse defn("import BBB 0002",
|
597
670
|
"B: BBB::B",
|
598
671
|
" e = d + 3",
|
599
672
|
), sset
|
600
673
|
|
601
|
-
engine.evaluate_attrs("B", ["a", "b", "c", "d", "e"]).should ==
|
674
|
+
engine.evaluate_attrs("B", ["a", "b", "c", "d", "e"]).should ==
|
675
|
+
[111, 222, {"b"=>-2}, 222, 225]
|
602
676
|
|
603
677
|
e4 = sset.get_engine("CCC", "0003")
|
604
678
|
|
605
|
-
e4.evaluate_attrs("B", ["a", "b", "c", "d", "e"]).should ==
|
679
|
+
e4.evaluate_attrs("B", ["a", "b", "c", "d", "e"]).should ==
|
680
|
+
[111, 222, {"b"=>-2}, 222, 666]
|
681
|
+
|
606
682
|
e4.evaluate_attrs("C", ["a", "b", "d"]).should == [123, 123*2, 123*3*2]
|
607
683
|
end
|
608
684
|
|
685
|
+
it "should eval imports (3)" do
|
686
|
+
sset.merge({
|
687
|
+
["BBB", "0002"] => getattr_code,
|
688
|
+
["CCC", "0003"] =>
|
689
|
+
defn("import BBB 0002",
|
690
|
+
"X:",
|
691
|
+
" xx = [n.x for n in @BBB::D('xs').xs]",
|
692
|
+
" yy = [n.x for n in BBB::D.xs]",
|
693
|
+
),
|
694
|
+
})
|
695
|
+
|
696
|
+
e4 = sset.get_engine("CCC", "0003")
|
697
|
+
e4.evaluate("X", "xx").should == [1,2,3]
|
698
|
+
e4.evaluate("X", "yy").should == [1,2,3]
|
699
|
+
end
|
700
|
+
|
701
|
+
it "can eval indexing" do
|
702
|
+
engine.parse defn("A:",
|
703
|
+
" a = [1,2,3]",
|
704
|
+
" b = a[1]",
|
705
|
+
" c = a[-1]",
|
706
|
+
" d = {'a' : 123, 'b': 456}",
|
707
|
+
" e = d['b']",
|
708
|
+
)
|
709
|
+
r = engine.evaluate_attrs("A", ["b", "c", "e"])
|
710
|
+
r.should == [2, 3, 456]
|
711
|
+
end
|
712
|
+
|
609
713
|
end
|
data/spec/func_spec.rb
CHANGED
@@ -68,6 +68,28 @@ describe "Delorean" do
|
|
68
68
|
r.should == [12.35, 12.3, 12]
|
69
69
|
end
|
70
70
|
|
71
|
+
it "should handle NUMBER" do
|
72
|
+
engine.parse defn("A:",
|
73
|
+
" a = NUMBER(12.3456)",
|
74
|
+
" b = NUMBER('12.3456')",
|
75
|
+
" c = NUMBER('12')",
|
76
|
+
)
|
77
|
+
|
78
|
+
r = engine.evaluate_attrs("A", ["a", "b", "c"])
|
79
|
+
r.should == [12.3456, 12.3456, 12]
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should handle STRING" do
|
83
|
+
engine.parse defn("A:",
|
84
|
+
" a = STRING('hello')",
|
85
|
+
" b = STRING(12.3456)",
|
86
|
+
" c = STRING([1,2,3])",
|
87
|
+
)
|
88
|
+
|
89
|
+
r = engine.evaluate_attrs("A", ["a", "b", "c"])
|
90
|
+
r.should == ["hello", '12.3456', [1,2,3].to_s]
|
91
|
+
end
|
92
|
+
|
71
93
|
it "should handle TIMEPART" do
|
72
94
|
engine.parse defn("A:",
|
73
95
|
" p =?",
|
@@ -147,14 +169,6 @@ describe "Delorean" do
|
|
147
169
|
expect { engine.evaluate_attrs("A", ["x"], {"p" => p}) }.to raise_error
|
148
170
|
end
|
149
171
|
|
150
|
-
it "should handle INDEX" do
|
151
|
-
engine.parse defn("A:",
|
152
|
-
" a = [INDEX([0, 11, 22, 33], i) for i in [1,2]]",
|
153
|
-
)
|
154
|
-
|
155
|
-
engine.evaluate("A", "a").should == [11,22]
|
156
|
-
end
|
157
|
-
|
158
172
|
it "should handle FLATTEN" do
|
159
173
|
x = [[1,2,[3]], 4, 5, [6]]
|
160
174
|
|
@@ -179,14 +193,4 @@ describe "Delorean" do
|
|
179
193
|
}.should raise_error("xx, 1, 2, 3")
|
180
194
|
|
181
195
|
end
|
182
|
-
|
183
|
-
it "should handle SYM" do
|
184
|
-
engine.parse defn("S:",
|
185
|
-
' a = TOSYM("hello")',
|
186
|
-
)
|
187
|
-
|
188
|
-
r = engine.evaluate("S", "a")
|
189
|
-
r.should == :hello
|
190
|
-
end
|
191
|
-
|
192
196
|
end
|
data/spec/parse_spec.rb
CHANGED
@@ -44,6 +44,12 @@ describe "Delorean" do
|
|
44
44
|
)
|
45
45
|
end
|
46
46
|
|
47
|
+
it "can parse indexing" do
|
48
|
+
engine.parse defn("A:",
|
49
|
+
" b = [1,2,3][1]",
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
47
53
|
it "should accept default param definitions" do
|
48
54
|
lambda {
|
49
55
|
engine.parse defn("A:",
|
@@ -122,6 +128,13 @@ describe "Delorean" do
|
|
122
128
|
|
123
129
|
end
|
124
130
|
|
131
|
+
it "should allow getattr in expressions" do
|
132
|
+
engine.parse defn("A:",
|
133
|
+
" a = 1",
|
134
|
+
" b = A.a * A.a - A.a",
|
135
|
+
)
|
136
|
+
end
|
137
|
+
|
125
138
|
it "should allow non-recursive code 1" do
|
126
139
|
# this is not a recursion error
|
127
140
|
engine.parse defn("A:",
|
@@ -588,6 +601,14 @@ describe "Delorean" do
|
|
588
601
|
engine.reset
|
589
602
|
end
|
590
603
|
|
604
|
+
it "should allow nodes as values" do
|
605
|
+
engine.parse defn("A:",
|
606
|
+
" a = 123",
|
607
|
+
"B:",
|
608
|
+
" a = A",
|
609
|
+
)
|
610
|
+
end
|
611
|
+
|
591
612
|
it "should parse module calls" do
|
592
613
|
engine.parse defn("A:",
|
593
614
|
" a = 123",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: delorean_lang
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.38
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,24 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: treetop
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '
|
21
|
+
version: '1.4'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '1.4'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: activerecord
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- Rakefile
|
91
91
|
- delorean.gemspec
|
92
92
|
- lib/delorean/base.rb
|
93
|
+
- lib/delorean/const.rb
|
93
94
|
- lib/delorean/container.rb
|
94
95
|
- lib/delorean/delorean.rb
|
95
96
|
- lib/delorean/delorean.treetop
|