delorean_lang 0.3.4 → 0.3.5

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,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: