delorean_lang 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZmY2MTM0OTE2NDc5ZmI2NWM1YzlkN2VjNzc4YjBmMjM3ZTJjZjMyZg==
5
- data.tar.gz: !binary |-
6
- OWYyZGNmYTFlY2I0YmM1ZDhlMDJlN2E5NzcwMDcxYWI3NDY0NmQwZA==
2
+ SHA1:
3
+ metadata.gz: 4146a779b717256081386c0769bbd102ebfd63da
4
+ data.tar.gz: 82006f8a19e563ddf112ef647dd29d8be0490a4a
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MzU5MWM3ZjMyYjBhZmU3ZDRkMjlhMzE3MmUzZDFhZDg0N2U1ZDc1N2E4OWM4
10
- ZTkyOWM4ZGJiMzFlMWZjN2RlODQxZTYxOGRkMWY3ODQ5NGIzN2YwMWVkYTJj
11
- NjdjMzJjNjBjMDAyYjcyZGQwNjkyNGQwZGVjMjc1ZTk2Mjc0Njc=
12
- data.tar.gz: !binary |-
13
- ZjliYWVkY2E2YTgzN2UyNDcyNTdmNGQ5ODg4MjY0MjVhNjcxNjZhNWI3ZGEx
14
- NTlmYWUzZjg2NGI2M2NkNTY1YWJmN2U3YzljZDgwZTg5YmRiNTI2ZmFiYjFl
15
- YmU3Zjc3YTNhYjg1NDljMWM0NmRiYjg4NmM2NmFhY2Y2YWE1NDk=
6
+ metadata.gz: b913c68e3a21abd3ca0dabaf5be811064e73f54bb3a7639daa7a55755c4aa2a743eb9df9a36c68464c8a76935d4607fc9ac4570cf75d99cd1436c2c1121daa17
7
+ data.tar.gz: ace534f8f6ffd10a0f27524e7afc595963e4d5b60f5e7ac2ce4423e65a808b399f730ff3263c2965fdf64d9ad214799c29fb84c23e94178f6441d1961ba593b9
@@ -14,8 +14,8 @@ Gem::Specification.new do |gem|
14
14
  gem.require_paths = ["lib"]
15
15
  gem.version = Delorean::VERSION
16
16
 
17
- gem.add_dependency "treetop", "~> 1.4"
18
- gem.add_dependency "activerecord", "~> 3.2.12"
17
+ gem.add_dependency "treetop", "~> 1.4.8"
18
+ gem.add_dependency "activerecord"
19
19
  gem.add_development_dependency "rspec"
20
20
  gem.add_development_dependency "sqlite3"
21
21
  end
@@ -1,4 +1,5 @@
1
1
  require 'active_support/time'
2
+ require 'bigdecimal'
2
3
 
3
4
  module Delorean
4
5
 
@@ -10,10 +11,10 @@ module Delorean
10
11
  compact: [Array],
11
12
  to_set: [Array],
12
13
  flatten: [Array, [Fixnum, nil]],
13
- length: [[Array, String]],
14
+ length: [Enumerable],
14
15
  max: [Array],
15
16
  member: "member?",
16
- member?: [Array, [Fixnum, String]],
17
+ member?: [Array, [Object]],
17
18
  reverse: [Array],
18
19
  slice: [Array, Fixnum, Fixnum],
19
20
  sort: [Array],
@@ -21,10 +22,10 @@ module Delorean
21
22
  uniq: [Array],
22
23
  sum: [Array],
23
24
  zip: [Array, [Array, Array, Array]],
24
- index: [Array,
25
- [Integer, Numeric, String, Array, Fixnum, Hash]],
25
+ index: [Array, [Object]],
26
26
  product: [Array, Array],
27
27
  first: [Enumerable, [nil, Fixnum]],
28
+ last: [Enumerable, [nil, Fixnum]],
28
29
  intersection: [Set, Enumerable],
29
30
  union: [Set, Enumerable],
30
31
 
@@ -117,6 +118,9 @@ module Delorean
117
118
  elsif obj.instance_of?(NodeCall)
118
119
  return obj.evaluate(attr)
119
120
  elsif obj.instance_of?(Hash)
121
+ # FIXME: this implementation doesn't handle something like
122
+ # {}.length. i.e. length is a whitelisted function, but not
123
+ # an attr. This implementation returns nil instead of 0.
120
124
  return obj[attr] if obj.member?(attr)
121
125
  return attr.is_a?(String) ? obj[attr.to_sym] : nil
122
126
  elsif obj.instance_of?(Class) && (obj < BaseClass)
@@ -1171,6 +1171,100 @@ module Delorean
1171
1171
  r0
1172
1172
  end
1173
1173
 
1174
+ module UnpackArgs0
1175
+ def args
1176
+ elements[3]
1177
+ end
1178
+ end
1179
+
1180
+ module UnpackArgs1
1181
+ def arg0
1182
+ elements[0]
1183
+ end
1184
+
1185
+ def args_rest
1186
+ elements[1]
1187
+ end
1188
+ end
1189
+
1190
+ def _nt_unpack_args
1191
+ start_index = index
1192
+ if node_cache[:unpack_args].has_key?(index)
1193
+ cached = node_cache[:unpack_args][index]
1194
+ if cached
1195
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1196
+ @index = cached.interval.end
1197
+ end
1198
+ return cached
1199
+ end
1200
+
1201
+ i0, s0 = index, []
1202
+ r1 = _nt_identifier
1203
+ s0 << r1
1204
+ if r1
1205
+ i3, s3 = index, []
1206
+ r5 = _nt_sp
1207
+ if r5
1208
+ r4 = r5
1209
+ else
1210
+ r4 = instantiate_node(SyntaxNode,input, index...index)
1211
+ end
1212
+ s3 << r4
1213
+ if r4
1214
+ if has_terminal?(',', false, index)
1215
+ r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
1216
+ @index += 1
1217
+ else
1218
+ terminal_parse_failure(',')
1219
+ r6 = nil
1220
+ end
1221
+ s3 << r6
1222
+ if r6
1223
+ r8 = _nt_sp
1224
+ if r8
1225
+ r7 = r8
1226
+ else
1227
+ r7 = instantiate_node(SyntaxNode,input, index...index)
1228
+ end
1229
+ s3 << r7
1230
+ if r7
1231
+ r10 = _nt_unpack_args
1232
+ if r10
1233
+ r9 = r10
1234
+ else
1235
+ r9 = instantiate_node(SyntaxNode,input, index...index)
1236
+ end
1237
+ s3 << r9
1238
+ end
1239
+ end
1240
+ end
1241
+ if s3.last
1242
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
1243
+ r3.extend(UnpackArgs0)
1244
+ else
1245
+ @index = i3
1246
+ r3 = nil
1247
+ end
1248
+ if r3
1249
+ r2 = r3
1250
+ else
1251
+ r2 = instantiate_node(SyntaxNode,input, index...index)
1252
+ end
1253
+ s0 << r2
1254
+ end
1255
+ if s0.last
1256
+ r0 = instantiate_node(UnpackArgs,input, i0...index, s0)
1257
+ r0.extend(UnpackArgs1)
1258
+ else
1259
+ @index = i0
1260
+ r0 = nil
1261
+ end
1262
+
1263
+ node_cache[:unpack_args][start_index] = r0
1264
+
1265
+ r0
1266
+ end
1267
+
1174
1268
  module ListExpr0
1175
1269
  def sp
1176
1270
  elements[1]
@@ -1195,7 +1289,7 @@ module Delorean
1195
1289
  elements[5]
1196
1290
  end
1197
1291
 
1198
- def i
1292
+ def args
1199
1293
  elements[6]
1200
1294
  end
1201
1295
 
@@ -1282,7 +1376,7 @@ module Delorean
1282
1376
  r9 = _nt_sp
1283
1377
  s2 << r9
1284
1378
  if r9
1285
- r10 = _nt_identifier
1379
+ r10 = _nt_unpack_args
1286
1380
  s2 << r10
1287
1381
  if r10
1288
1382
  r11 = _nt_sp
@@ -1445,52 +1539,6 @@ module Delorean
1445
1539
  end
1446
1540
 
1447
1541
  module SetExpr0
1448
- def sp
1449
- elements[1]
1450
- end
1451
-
1452
- def e3
1453
- elements[2]
1454
- end
1455
-
1456
- end
1457
-
1458
- module SetExpr1
1459
- def e2
1460
- elements[2]
1461
- end
1462
-
1463
- def sp1
1464
- elements[3]
1465
- end
1466
-
1467
- def sp2
1468
- elements[5]
1469
- end
1470
-
1471
- def i
1472
- elements[6]
1473
- end
1474
-
1475
- def sp3
1476
- elements[7]
1477
- end
1478
-
1479
- def sp4
1480
- elements[9]
1481
- end
1482
-
1483
- def e1
1484
- elements[10]
1485
- end
1486
-
1487
- def ifexp
1488
- elements[12]
1489
- end
1490
-
1491
- end
1492
-
1493
- module SetExpr2
1494
1542
  def args
1495
1543
  elements[2]
1496
1544
  end
@@ -1537,117 +1585,32 @@ module Delorean
1537
1585
  end
1538
1586
  s2 << r4
1539
1587
  if r4
1540
- r6 = _nt_expression
1588
+ r6 = _nt_fn_args
1541
1589
  s2 << r6
1542
1590
  if r6
1543
- r7 = _nt_sp
1591
+ r8 = _nt_sp
1592
+ if r8
1593
+ r7 = r8
1594
+ else
1595
+ r7 = instantiate_node(SyntaxNode,input, index...index)
1596
+ end
1544
1597
  s2 << r7
1545
1598
  if r7
1546
- if has_terminal?('for', false, index)
1547
- r8 = instantiate_node(SyntaxNode,input, index...(index + 3))
1548
- @index += 3
1599
+ if has_terminal?('}', false, index)
1600
+ r9 = instantiate_node(SyntaxNode,input, index...(index + 1))
1601
+ @index += 1
1549
1602
  else
1550
- terminal_parse_failure('for')
1551
- r8 = nil
1552
- end
1553
- s2 << r8
1554
- if r8
1555
- r9 = _nt_sp
1556
- s2 << r9
1557
- if r9
1558
- r10 = _nt_identifier
1559
- s2 << r10
1560
- if r10
1561
- r11 = _nt_sp
1562
- s2 << r11
1563
- if r11
1564
- if has_terminal?('in', false, index)
1565
- r12 = instantiate_node(SyntaxNode,input, index...(index + 2))
1566
- @index += 2
1567
- else
1568
- terminal_parse_failure('in')
1569
- r12 = nil
1570
- end
1571
- s2 << r12
1572
- if r12
1573
- r13 = _nt_sp
1574
- s2 << r13
1575
- if r13
1576
- r14 = _nt_expression
1577
- s2 << r14
1578
- if r14
1579
- r16 = _nt_sp
1580
- if r16
1581
- r15 = r16
1582
- else
1583
- r15 = instantiate_node(SyntaxNode,input, index...index)
1584
- end
1585
- s2 << r15
1586
- if r15
1587
- i18, s18 = index, []
1588
- if has_terminal?('if', false, index)
1589
- r19 = instantiate_node(SyntaxNode,input, index...(index + 2))
1590
- @index += 2
1591
- else
1592
- terminal_parse_failure('if')
1593
- r19 = nil
1594
- end
1595
- s18 << r19
1596
- if r19
1597
- r20 = _nt_sp
1598
- s18 << r20
1599
- if r20
1600
- r21 = _nt_expression
1601
- s18 << r21
1602
- if r21
1603
- r23 = _nt_sp
1604
- if r23
1605
- r22 = r23
1606
- else
1607
- r22 = instantiate_node(SyntaxNode,input, index...index)
1608
- end
1609
- s18 << r22
1610
- end
1611
- end
1612
- end
1613
- if s18.last
1614
- r18 = instantiate_node(SyntaxNode,input, i18...index, s18)
1615
- r18.extend(SetExpr0)
1616
- else
1617
- @index = i18
1618
- r18 = nil
1619
- end
1620
- if r18
1621
- r17 = r18
1622
- else
1623
- r17 = instantiate_node(SyntaxNode,input, index...index)
1624
- end
1625
- s2 << r17
1626
- if r17
1627
- if has_terminal?('}', false, index)
1628
- r24 = instantiate_node(SyntaxNode,input, index...(index + 1))
1629
- @index += 1
1630
- else
1631
- terminal_parse_failure('}')
1632
- r24 = nil
1633
- end
1634
- s2 << r24
1635
- end
1636
- end
1637
- end
1638
- end
1639
- end
1640
- end
1641
- end
1642
- end
1603
+ terminal_parse_failure('}')
1604
+ r9 = nil
1643
1605
  end
1606
+ s2 << r9
1644
1607
  end
1645
1608
  end
1646
1609
  end
1647
1610
  end
1648
1611
  if s2.last
1649
- r2 = instantiate_node(SetComprehension,input, i2...index, s2)
1650
- r2.extend(SetExpr1)
1612
+ r2 = instantiate_node(SetExpr,input, i2...index, s2)
1613
+ r2.extend(SetExpr0)
1651
1614
  else
1652
1615
  @index = i2
1653
1616
  r2 = nil
@@ -1655,60 +1618,8 @@ module Delorean
1655
1618
  if r2
1656
1619
  r0 = r2
1657
1620
  else
1658
- i25, s25 = index, []
1659
- if has_terminal?('{', false, index)
1660
- r26 = instantiate_node(SyntaxNode,input, index...(index + 1))
1661
- @index += 1
1662
- else
1663
- terminal_parse_failure('{')
1664
- r26 = nil
1665
- end
1666
- s25 << r26
1667
- if r26
1668
- r28 = _nt_sp
1669
- if r28
1670
- r27 = r28
1671
- else
1672
- r27 = instantiate_node(SyntaxNode,input, index...index)
1673
- end
1674
- s25 << r27
1675
- if r27
1676
- r29 = _nt_fn_args
1677
- s25 << r29
1678
- if r29
1679
- r31 = _nt_sp
1680
- if r31
1681
- r30 = r31
1682
- else
1683
- r30 = instantiate_node(SyntaxNode,input, index...index)
1684
- end
1685
- s25 << r30
1686
- if r30
1687
- if has_terminal?('}', false, index)
1688
- r32 = instantiate_node(SyntaxNode,input, index...(index + 1))
1689
- @index += 1
1690
- else
1691
- terminal_parse_failure('}')
1692
- r32 = nil
1693
- end
1694
- s25 << r32
1695
- end
1696
- end
1697
- end
1698
- end
1699
- if s25.last
1700
- r25 = instantiate_node(SetExpr,input, i25...index, s25)
1701
- r25.extend(SetExpr2)
1702
- else
1703
- @index = i25
1704
- r25 = nil
1705
- end
1706
- if r25
1707
- r0 = r25
1708
- else
1709
- @index = i0
1710
- r0 = nil
1711
- end
1621
+ @index = i0
1622
+ r0 = nil
1712
1623
  end
1713
1624
  end
1714
1625
 
@@ -1745,7 +1656,7 @@ module Delorean
1745
1656
  elements[9]
1746
1657
  end
1747
1658
 
1748
- def i
1659
+ def args
1749
1660
  elements[10]
1750
1661
  end
1751
1662
 
@@ -1860,7 +1771,7 @@ module Delorean
1860
1771
  r15 = _nt_sp
1861
1772
  s2 << r15
1862
1773
  if r15
1863
- r16 = _nt_identifier
1774
+ r16 = _nt_unpack_args
1864
1775
  s2 << r16
1865
1776
  if r16
1866
1777
  r17 = _nt_sp
@@ -55,11 +55,16 @@ grammar Delorean
55
55
  '.' sp? i:(identifier / integer) <GetAttr>
56
56
  end
57
57
 
58
+ rule unpack_args
59
+ arg0:identifier args_rest:(sp? ',' sp? args:unpack_args?)? <UnpackArgs>
60
+ end
61
+
58
62
  rule list_expr
59
63
  '[]' <ListExpr>
60
64
  /
61
65
  '[' sp? e2:expression sp
62
- 'for' sp i:identifier sp 'in' sp e1:expression sp?
66
+ 'for' sp args:unpack_args sp
67
+ 'in' sp e1:expression sp?
63
68
  ifexp:('if' sp e3:expression sp?)?
64
69
  ']' <ListComprehension>
65
70
  /
@@ -69,11 +74,6 @@ grammar Delorean
69
74
  rule set_expr
70
75
  '{-}' <SetExpr>
71
76
  /
72
- '{' sp? e2:expression sp
73
- 'for' sp i:identifier sp 'in' sp e1:expression sp?
74
- ifexp:('if' sp e3:expression sp?)?
75
- '}' <SetComprehension>
76
- /
77
77
  '{' sp? args:fn_args sp? '}' <SetExpr>
78
78
  end
79
79
 
@@ -81,7 +81,8 @@ grammar Delorean
81
81
  '{}' <HashExpr>
82
82
  /
83
83
  '{' sp? el:expression sp? ':' sp? er:expression sp
84
- 'for' sp i:identifier sp 'in' sp e1:expression sp?
84
+ 'for' sp args:unpack_args sp
85
+ 'in' sp e1:expression sp?
85
86
  ifexp:('if' sp ei:expression sp?)?
86
87
  '}' <HashComprehension>
87
88
  /
@@ -404,31 +404,51 @@ eos
404
404
  end
405
405
  end
406
406
 
407
- class ListComprehension < SNode
407
+ class UnpackArgs < SNode
408
408
  def check(context, *)
409
- vname = i.text_value
409
+ [arg0.text_value] +
410
+ (defined?(args_rest.args) && !args_rest.args.text_value.empty? ?
411
+ args_rest.args.check(context) : [])
412
+ end
410
413
 
414
+ def rewrite(context)
415
+ arg0.rewrite(context) +
416
+ (defined?(args_rest.args) && !args_rest.args.text_value.empty? ?
417
+ ", " + args_rest.args.rewrite(context) : "")
418
+ end
419
+ end
420
+
421
+ class ListComprehension < SNode
422
+ def check(context, *)
423
+ unpack_vars = args.check(context)
411
424
  e1c = e1.check(context)
412
- context.parse_define_var(vname)
425
+ unpack_vars.each {|vname| context.parse_define_var(vname)}
426
+
413
427
  # need to check e2/e3 in a context where the comprehension var
414
428
  # is defined.
415
429
  e2c = e2.check(context)
416
430
  e3c = defined?(ifexp.e3) ? ifexp.e3.check(context) : []
417
431
 
418
- context.parse_undef_var(vname)
419
- e2c.delete(vname)
420
- e3c.delete(vname)
432
+ unpack_vars.each {
433
+ |vname|
434
+ context.parse_undef_var(vname)
435
+ e2c.delete(vname)
436
+ e3c.delete(vname)
437
+ }
421
438
 
422
439
  e1c + e2c + e3c
423
440
  end
424
441
 
425
442
  def rewrite(context)
426
443
  res = "(#{e1.rewrite(context)})"
427
- context.parse_define_var(i.text_value)
428
- res += ".select{|#{i.rewrite(context)}|(#{ifexp.e3.rewrite(context)})}" if
444
+ unpack_vars = args.check(context)
445
+ unpack_vars.each {|vname| context.parse_define_var(vname)}
446
+ args_str = args.rewrite(context)
447
+
448
+ res += ".select{|#{args_str}|(#{ifexp.e3.rewrite(context)})}" if
429
449
  defined?(ifexp.e3)
430
- res += ".map{|#{i.rewrite(context)}| (#{e2.rewrite(context)}) }"
431
- context.parse_undef_var(i.text_value)
450
+ res += ".map{|#{args_str}| (#{e2.rewrite(context)}) }"
451
+ unpack_vars.each {|vname| context.parse_undef_var(vname)}
432
452
  res
433
453
  end
434
454
  end
@@ -439,41 +459,45 @@ eos
439
459
  end
440
460
  end
441
461
 
442
- class SetComprehension < ListComprehension
443
- def rewrite(context)
444
- "Set[*#{super}]"
445
- end
446
- end
447
-
448
462
  class HashComprehension < SNode
449
- def check(context, *)
450
- vname = i.text_value
463
+ # used in generating unique hash names
464
+ @@comp_count = 0
451
465
 
466
+ def check(context, *)
467
+ unpack_vars = args.check(context)
452
468
  e1c = e1.check(context)
453
- context.parse_define_var(vname)
469
+ unpack_vars.each {|vname| context.parse_define_var(vname)}
470
+
454
471
  # need to check el/er/ei in a context where the comprehension var
455
472
  # is defined.
456
473
  elc = el.check(context)
457
474
  erc = er.check(context)
458
475
  eic = defined?(ifexp.ei) ? ifexp.ei.check(context) : []
459
476
 
460
- context.parse_undef_var(vname)
461
- elc.delete(vname)
462
- erc.delete(vname)
463
- eic.delete(vname)
464
-
477
+ unpack_vars.each {
478
+ |vname|
479
+ context.parse_undef_var(vname)
480
+ elc.delete(vname)
481
+ erc.delete(vname)
482
+ eic.delete(vname)
483
+ }
465
484
  e1c + elc + erc + eic
466
485
  end
467
486
 
468
487
  def rewrite(context)
469
488
  res = "(#{e1.rewrite(context)})"
470
- context.parse_define_var(i.text_value)
471
- iw = i.rewrite(context)
472
- res += ".select{|#{iw}| (#{ifexp.ei.rewrite(context)}) }" if
489
+ unpack_vars = args.check(context)
490
+ unpack_vars.each {|vname| context.parse_define_var(vname)}
491
+ args_str = args.rewrite(context)
492
+
493
+ hid = @@comp_count += 1
494
+
495
+ res += ".select{|#{args_str}| (#{ifexp.ei.rewrite(context)}) }" if
473
496
  defined?(ifexp.ei)
474
- res += ".inject({}){|_h#{iw}, #{iw}| " +
475
- "_h#{iw}[#{el.rewrite(context)}]=(#{er.rewrite(context)}); _h#{iw}}"
476
- context.parse_undef_var(i.text_value)
497
+ res += ".each_with_object({}){|(#{args_str}), _h#{hid}| " +
498
+ "_h#{hid}[#{el.rewrite(context)}]=(#{er.rewrite(context)})}"
499
+
500
+ unpack_vars.each {|vname| context.parse_undef_var(vname)}
477
501
  res
478
502
  end
479
503
  end
@@ -484,7 +508,7 @@ eos
484
508
  end
485
509
 
486
510
  def rewrite(context)
487
- "{" + (defined?(args) ? args.rewrite(context) : "") + "}"
511
+ "{#{args.rewrite(context) if defined?(args)}}"
488
512
  end
489
513
  end
490
514
 
@@ -1,3 +1,3 @@
1
1
  module Delorean
2
- VERSION = "0.3.4"
2
+ VERSION = "0.3.5"
3
3
  end
@@ -534,14 +534,13 @@ eof
534
534
  ]
535
535
  end
536
536
 
537
- it "should eval sets and set comprehension" do
537
+ it "should eval sets" do
538
538
  engine.parse defn("A:",
539
539
  " a = {-}",
540
- " b = {i*5 for i in {1,2,3}}",
541
540
  " c = {1,2,3} | {4,5}",
542
541
  )
543
- engine.evaluate_attrs("A", ["a", "b", "c"]).should ==
544
- [Set[], Set[5,10,15], Set[1,2,3,4,5]]
542
+ engine.evaluate_attrs("A", ["a", "c"]).should ==
543
+ [Set[], Set[1,2,3,4,5]]
545
544
  end
546
545
 
547
546
  it "should eval list comprehension" do
@@ -583,6 +582,13 @@ eof
583
582
  engine.evaluate("A", "c").should == [0.5]
584
583
  end
585
584
 
585
+ it "should handle list comprehension unpacking" do
586
+ engine.parse defn("A:",
587
+ " b = [a-b for a, b in [[1,2],[20,10]]]",
588
+ )
589
+ engine.evaluate("A", "b").should == [-1, 10]
590
+ end
591
+
586
592
  it "should eval hashes" do
587
593
  engine.parse defn("A:",
588
594
  " b = {}",
@@ -638,6 +644,13 @@ eof
638
644
  engine.evaluate_attrs("A", ["d", "f"]).should == [26, 2]
639
645
  end
640
646
 
647
+ it "should eval multi-var hash comprehension" do
648
+ engine.parse defn("A:",
649
+ " b = {k*5 : v+1 for k, v in {1:2, 7:-30}}",
650
+ )
651
+ engine.evaluate("A", "b").should == {5=>3, 35=>-29}
652
+ end
653
+
641
654
  it "should be able to amend node calls" do
642
655
  engine.parse defn("A:",
643
656
  " a =?",
@@ -101,7 +101,9 @@ describe "Delorean" do
101
101
  r.should == [p.year, p.day, p.month]
102
102
 
103
103
  # Non date argument should raise an error
104
- expect { engine.evaluate_attrs("A", ["y", "d", "m"], {"p" => 123}) }.to raise_error
104
+ expect {
105
+ engine.evaluate_attrs("A", ["y", "d", "m"], {"p" => 123})
106
+ }.to raise_error
105
107
  end
106
108
 
107
109
  it "should handle FLATTEN" do
@@ -139,10 +141,11 @@ describe "Delorean" do
139
141
  " dd = d.flatten()",
140
142
  " e = dd.sort()",
141
143
  " f = e.uniq()",
142
- " g = e.length()",
144
+ " g = e.length",
143
145
  " gg = a.length()",
144
146
  " l = a.member(5)",
145
147
  " m = [a.member(5), a.member(55)]",
148
+ " n = {'a':1, 'b':2, 'c':3}.length()",
146
149
  )
147
150
 
148
151
  engine.evaluate("A", "c").should == x.flatten(1)
@@ -153,6 +156,20 @@ describe "Delorean" do
153
156
  engine.evaluate("A", "g").should == dd.length
154
157
  engine.evaluate("A", "gg").should == x.length
155
158
  engine.evaluate("A", "m").should == [x.member?(5), x.member?(55)]
159
+ engine.evaluate("A", "n").should == 3
160
+ end
161
+
162
+ it "should be able to call function on hash" do
163
+ # FIXME: this is actually a Delorean design issue. How do
164
+ # whitelisted functions interact with attrs? In this case, we
165
+ # return nil since there is no Delorean 'length' attr in the hash.
166
+
167
+ engine.parse defn("A:",
168
+ " n = {}.length",
169
+ " m = {'length':100}.length",
170
+ )
171
+ engine.evaluate("A", "n").should == 0
172
+ engine.evaluate("A", "m").should == 100
156
173
  end
157
174
 
158
175
  it "should handle RUBY slice function" do
@@ -638,6 +638,12 @@ describe "Delorean" do
638
638
  engine.reset
639
639
  end
640
640
 
641
+ it "should accept hash comprehension 2-var unpacking" do
642
+ engine.parse defn("A:",
643
+ " b = [ a+b for a, b in [] ]",
644
+ )
645
+ end
646
+
641
647
  it "should allow nodes as values" do
642
648
  engine.parse defn("A:",
643
649
  " a = 123",
@@ -32,7 +32,6 @@ end
32
32
  class Dummy < ActiveRecord::Base
33
33
  include Delorean::Model
34
34
 
35
- attr_accessible :name, :number, :dummy
36
35
  belongs_to :dummy
37
36
 
38
37
  def self.i_just_met_you(name, number)
metadata CHANGED
@@ -1,69 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delorean_lang
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arman Bostani
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-21 00:00:00.000000000 Z
11
+ date: 2014-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: treetop
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.4'
19
+ version: 1.4.8
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.4'
26
+ version: 1.4.8
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 3.2.12
33
+ version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 3.2.12
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: sqlite3
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  description: A "compiler" for the Delorean programming language
@@ -73,8 +73,8 @@ executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
- - .gitignore
77
- - .rspec
76
+ - ".gitignore"
77
+ - ".rspec"
78
78
  - Gemfile
79
79
  - LICENSE
80
80
  - README.md
@@ -105,17 +105,17 @@ require_paths:
105
105
  - lib
106
106
  required_ruby_version: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ! '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  required_rubygems_version: !ruby/object:Gem::Requirement
112
112
  requirements:
113
- - - ! '>='
113
+ - - ">="
114
114
  - !ruby/object:Gem::Version
115
115
  version: '0'
116
116
  requirements: []
117
117
  rubyforge_project:
118
- rubygems_version: 2.1.11
118
+ rubygems_version: 2.2.2
119
119
  signing_key:
120
120
  specification_version: 4
121
121
  summary: Delorean compiler
@@ -125,4 +125,3 @@ test_files:
125
125
  - spec/func_spec.rb
126
126
  - spec/parse_spec.rb
127
127
  - spec/spec_helper.rb
128
- has_rdoc: