HDLRuby 2.5.1 → 2.6.8

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/HDLRuby/hdr_samples/adder.rb +1 -1
  3. data/lib/HDLRuby/hdr_samples/adder_bench.rb +1 -1
  4. data/lib/HDLRuby/hdr_samples/adder_gen.rb +1 -1
  5. data/lib/HDLRuby/hdr_samples/comparison_bench.rb +40 -0
  6. data/lib/HDLRuby/hdr_samples/constant_in_function.rb +27 -0
  7. data/lib/HDLRuby/hdr_samples/dff_unit.rb +3 -3
  8. data/lib/HDLRuby/hdr_samples/huge_rom.rb +25 -0
  9. data/lib/HDLRuby/hdr_samples/logic_bench.rb +21 -0
  10. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +1 -1
  11. data/lib/HDLRuby/hdr_samples/multi_timed_bench.rb +54 -0
  12. data/lib/HDLRuby/hdr_samples/music.rb +79 -0
  13. data/lib/HDLRuby/hdr_samples/named_sub.rb +42 -0
  14. data/lib/HDLRuby/hdr_samples/rom.rb +16 -0
  15. data/lib/HDLRuby/hdr_samples/type_minmax_bench.rb +37 -0
  16. data/lib/HDLRuby/hdr_samples/with_function_generator.rb +25 -0
  17. data/lib/HDLRuby/hdr_samples/with_to_array.rb +29 -0
  18. data/lib/HDLRuby/hdrcc.rb +69 -9
  19. data/lib/HDLRuby/hruby_decorator.rb +3 -1
  20. data/lib/HDLRuby/hruby_high.rb +220 -29
  21. data/lib/HDLRuby/hruby_low.rb +433 -45
  22. data/lib/HDLRuby/hruby_low2c.rb +122 -168
  23. data/lib/HDLRuby/hruby_low2hdr.rb +738 -0
  24. data/lib/HDLRuby/hruby_low2high.rb +331 -549
  25. data/lib/HDLRuby/hruby_low2vhd.rb +39 -2
  26. data/lib/HDLRuby/hruby_low_bool2select.rb +29 -0
  27. data/lib/HDLRuby/hruby_low_casts_without_expression.rb +27 -0
  28. data/lib/HDLRuby/hruby_low_fix_types.rb +25 -0
  29. data/lib/HDLRuby/hruby_low_mutable.rb +70 -0
  30. data/lib/HDLRuby/hruby_low_resolve.rb +28 -0
  31. data/lib/HDLRuby/hruby_low_without_connection.rb +6 -3
  32. data/lib/HDLRuby/hruby_low_without_namespace.rb +7 -4
  33. data/lib/HDLRuby/hruby_low_without_select.rb +13 -0
  34. data/lib/HDLRuby/hruby_tools.rb +11 -1
  35. data/lib/HDLRuby/hruby_verilog.rb +1572 -1723
  36. data/lib/HDLRuby/sim/hruby_sim.h +45 -5
  37. data/lib/HDLRuby/sim/hruby_sim_calc.c +192 -20
  38. data/lib/HDLRuby/sim/hruby_sim_core.c +24 -9
  39. data/lib/HDLRuby/sim/hruby_sim_vcd.c +7 -3
  40. data/lib/HDLRuby/sim/hruby_sim_vizualize.c +22 -6
  41. data/lib/HDLRuby/std/fixpoint.rb +9 -0
  42. data/lib/HDLRuby/std/function_generator.rb +139 -0
  43. data/lib/HDLRuby/std/hruby_unit.rb +75 -0
  44. data/lib/HDLRuby/version.rb +1 -1
  45. metadata +18 -6
  46. data/lib/HDLRuby/hruby_unit.rb +0 -43
@@ -1276,6 +1276,18 @@ module HDLRuby::Low
1276
1276
  end
1277
1277
  end
1278
1278
 
1279
+ # Gets the type max value if any.
1280
+ # Default: not defined.
1281
+ def max
1282
+ raise AnyError, "No max value for type #{self}"
1283
+ end
1284
+
1285
+ # Gets the type min value if any.
1286
+ # Default: not defined.
1287
+ def min
1288
+ raise AnyError, "No min value for type #{self}"
1289
+ end
1290
+
1279
1291
  # Get the direction of the type, little or big endian.
1280
1292
  def direction
1281
1293
  # By default, little endian.
@@ -1317,6 +1329,11 @@ module HDLRuby::Low
1317
1329
  return false
1318
1330
  end
1319
1331
 
1332
+ # Tells if the type is hierarchical.
1333
+ def hierarchical?
1334
+ return self.base? || self.types?
1335
+ end
1336
+
1320
1337
  # Tell if +type+ is equivalent to current type.
1321
1338
  #
1322
1339
  # NOTE: type can be compatible while not being equivalent, please
@@ -1359,10 +1376,6 @@ module HDLRuby::Low
1359
1376
  # The void type.
1360
1377
  class << (Void = Type.new(:void) )
1361
1378
  include LLeaf
1362
- # # Get the base type, actually self for leaf types.
1363
- # def base
1364
- # self
1365
- # end
1366
1379
  end
1367
1380
 
1368
1381
  ##
@@ -1465,6 +1478,11 @@ module HDLRuby::Low
1465
1478
  # end
1466
1479
  end
1467
1480
 
1481
+ ##
1482
+ # The void type.
1483
+ class << (StringT = Type.new(:string) )
1484
+ include LLeaf
1485
+ end
1468
1486
 
1469
1487
 
1470
1488
  ##
@@ -1473,9 +1491,6 @@ module HDLRuby::Low
1473
1491
  # NOTE: type definition are actually type with a name refering to another
1474
1492
  # type (and equivalent to it).
1475
1493
  class TypeDef < Type
1476
- # Moved to constructor
1477
- # extend Forwardable
1478
-
1479
1494
  # The definition of the type.
1480
1495
  attr_reader :def
1481
1496
 
@@ -1533,15 +1548,6 @@ module HDLRuby::Low
1533
1548
 
1534
1549
  alias_method :each_deep, :each_type_deep
1535
1550
 
1536
- # Moved to constructor
1537
- # # Delegate the type methods to the ref.
1538
- # def_delegators :@def,
1539
- # :signed?, :unsigned?, :fixed?, :float?, :leaf?,
1540
- # :width, :range?, :range, :base?, :base, :types?,
1541
- # :get_all_types, :get_type, :each, :each_type,
1542
- # :regular?,
1543
- # :each_name,
1544
- # :equivalent?
1545
1551
  end
1546
1552
 
1547
1553
 
@@ -1623,6 +1629,25 @@ module HDLRuby::Low
1623
1629
  return @base.width * ((first-last).abs + 1)
1624
1630
  end
1625
1631
 
1632
+ # Gets the type max value if any.
1633
+ def max
1634
+ if (self.signed?) then
1635
+ return (2**(self.width-1))-1
1636
+ else
1637
+ return (2**(self.width))-1
1638
+ end
1639
+ end
1640
+
1641
+ # Gets the type min value if any.
1642
+ # Default: not defined.
1643
+ def min
1644
+ if (self.signed?) then
1645
+ return -(2**(self.width-1))
1646
+ else
1647
+ return 0
1648
+ end
1649
+ end
1650
+
1626
1651
  # Get the direction of the type, little or big endian.
1627
1652
  def direction
1628
1653
  return @range.first < @range.last ? :big : :little
@@ -2401,6 +2426,12 @@ module HDLRuby::Low
2401
2426
  end
2402
2427
  end
2403
2428
 
2429
+ # Tells if the signal is immutable (cannot be written.)
2430
+ def immutable?
2431
+ # By default, signals are not immutable.
2432
+ false
2433
+ end
2434
+
2404
2435
  # Add decorator capability (modifies intialize to put after).
2405
2436
  include Hdecorator
2406
2437
 
@@ -2445,6 +2476,11 @@ module HDLRuby::Low
2445
2476
  ##
2446
2477
  # Describes a constant signal.
2447
2478
  class SignalC < SignalI
2479
+ # Tells if the signal is immutable (cannot be written.)
2480
+ def immutable?
2481
+ # Constant signals are immutable.
2482
+ true
2483
+ end
2448
2484
  end
2449
2485
 
2450
2486
  ##
@@ -2802,6 +2838,15 @@ module HDLRuby::Low
2802
2838
  "Internal error: hash is not defined for class: #{self.class}"
2803
2839
  end
2804
2840
 
2841
+ # Iterates over each sub statement if any.
2842
+ #
2843
+ # Returns an enumerator if no ruby block is given.
2844
+ def each_statement(&ruby_block)
2845
+ # No ruby statement? Return an enumerator.
2846
+ return to_enum(:each_statement) unless ruby_block
2847
+ # By default: nothing to do.
2848
+ end
2849
+
2805
2850
  # Get the block of the statement.
2806
2851
  def block
2807
2852
  if self.is_a?(Block)
@@ -3114,7 +3159,24 @@ module HDLRuby::Low
3114
3159
  end
3115
3160
  end
3116
3161
 
3162
+ # Iterates over each sub statement if any.
3163
+ #
3164
+ # Returns an enumerator if no ruby block is given.
3165
+ def each_statement(&ruby_block)
3166
+ # No ruby block? Return an enumerator.
3167
+ return to_enum(:each_statement) unless ruby_block
3168
+ # A ruby block?
3169
+ # Appy it on the statement children.
3170
+ ruby_block.call(@yes)
3171
+ self.each_noif do |next_cond,next_yes|
3172
+ ruby_block.call(next_yes)
3173
+ end
3174
+ ruby_block.call(@no) if @no
3175
+ end
3176
+
3117
3177
  # Iterates over the children (including the condition).
3178
+ #
3179
+ # Returns an enumerator if no ruby block is given.
3118
3180
  def each_node(&ruby_block)
3119
3181
  # No ruby block? Return an enumerator.
3120
3182
  return to_enum(:each_node) unless ruby_block
@@ -3271,6 +3333,17 @@ module HDLRuby::Low
3271
3333
  return When.new(@match.clone,@statement.clone)
3272
3334
  end
3273
3335
 
3336
+ # Iterates over each sub statement if any.
3337
+ #
3338
+ # Returns an enumerator if no ruby block is given.
3339
+ def each_statement(&ruby_block)
3340
+ # No ruby block? Return an enumerator.
3341
+ return to_enum(:each_statement) unless ruby_block
3342
+ # A ruby block?
3343
+ # Appy it on the statement child.
3344
+ ruby_block.call(@statement)
3345
+ end
3346
+
3274
3347
  # Iterates over the sub blocks.
3275
3348
  def each_block(&ruby_block)
3276
3349
  # No ruby block? Return an enumerator.
@@ -3321,7 +3394,8 @@ module HDLRuby::Low
3321
3394
 
3322
3395
  # Gets the top block, i.e. the first block of the current behavior.
3323
3396
  def top_block
3324
- return self.parent.is_a?(Behavior) ? self : self.parent.top_block
3397
+ # return self.parent.is_a?(Behavior) ? self : self.parent.top_block
3398
+ return self.parent.top_block
3325
3399
  end
3326
3400
 
3327
3401
  # Tell if the statement includes a signal whose name is one of +names+.
@@ -3425,6 +3499,19 @@ module HDLRuby::Low
3425
3499
  @default
3426
3500
  end
3427
3501
 
3502
+ # Iterates over each sub statement if any.
3503
+ #
3504
+ # Returns an enumerator if no ruby block is given.
3505
+ def each_statement(&ruby_block)
3506
+ # No ruby block? Return an enumerator.
3507
+ return to_enum(:each_statement) unless ruby_block
3508
+ # A ruby block?
3509
+ # Apply on each when.
3510
+ @whens.each { |w| w.each_statement(&ruby_block) }
3511
+ # And on the default if any.
3512
+ ruby_block.call(@default) if @default
3513
+ end
3514
+
3428
3515
  # Iterates over the match cases.
3429
3516
  #
3430
3517
  # Returns an enumerator if no ruby block is given.
@@ -3571,6 +3658,122 @@ module HDLRuby::Low
3571
3658
  end
3572
3659
 
3573
3660
 
3661
+ ##
3662
+ # Describes a print statement: not synthesizable!
3663
+ class Print < Statement
3664
+
3665
+ # Creates a new statement for printing +args+.
3666
+ def initialize(*args)
3667
+ super()
3668
+ # Process the arguments.
3669
+ @args = args.map do |arg|
3670
+ arg.parent = self
3671
+ arg
3672
+ end
3673
+ end
3674
+
3675
+ # Comparison for hash: structural comparison.
3676
+ def eql?(obj)
3677
+ return false unless obj.is_a?(Print)
3678
+ return false if @args.each.zip(obj.each_arg).any? do |a0,a1|
3679
+ !a0.eql?(a1)
3680
+ end
3681
+ return true
3682
+ end
3683
+
3684
+ # Iterates over each argument.
3685
+ #
3686
+ # Returns an enumerator if no ruby block is given.
3687
+ def each_arg(&ruby_block)
3688
+ # No ruby block? Return an enumerator.
3689
+ return to_enum(:each_arg) unless ruby_block
3690
+ # A ruby block? First apply it to each argument.
3691
+ @args.each(&ruby_block)
3692
+ end
3693
+
3694
+ # Iterates over each object deeply.
3695
+ #
3696
+ # Returns an enumerator if no ruby block is given.
3697
+ def each_deep(&ruby_block)
3698
+ # No ruby block? Return an enumerator.
3699
+ return to_enum(:each_deep) unless ruby_block
3700
+ # A ruby block? First apply it to current.
3701
+ ruby_block.call(self)
3702
+ # Then apply on the arguments.
3703
+ self.each_arg(&ruby_block)
3704
+ end
3705
+
3706
+ # Hash function.
3707
+ def hash
3708
+ return @args.hash
3709
+ end
3710
+
3711
+ # Clones the TimeWait (deeply)
3712
+ def clone
3713
+ return Print.new(*@args.map { |arg| arg.clone })
3714
+ end
3715
+
3716
+ # Iterates over the expression children if any.
3717
+ def each_node(&ruby_block)
3718
+ # No ruby block? Return an enumerator.
3719
+ return to_enum(:each_node) unless ruby_block
3720
+ # A ruby block?
3721
+ # Apply it on each argument.
3722
+ @args.each(&ruby_block)
3723
+ end
3724
+
3725
+ # Iterates over the nodes deeply if any.
3726
+ def each_node_deep(&ruby_block)
3727
+ # No ruby block? Return an enumerator.
3728
+ return to_enum(:each_node_deep) unless ruby_block
3729
+ # A ruby block? First apply it to current.
3730
+ ruby_block.call(self)
3731
+ # And apply it on each argument.
3732
+ @args.each(&ruby_block)
3733
+ end
3734
+
3735
+ # Iterates over the sub blocks.
3736
+ def each_block(&ruby_block)
3737
+ # No ruby block? Return an enumerator.
3738
+ return to_enum(:each_block) unless ruby_block
3739
+ # A ruby block?
3740
+ # Recurse on each argument.
3741
+ @args.each do |arg|
3742
+ arg.each_block(&ruby_block) if arg.respond_to?(:each_block)
3743
+ end
3744
+ end
3745
+
3746
+ # Iterates over all the blocks contained in the current block.
3747
+ def each_block_deep(&ruby_block)
3748
+ # No ruby block? Return an enumerator.
3749
+ return to_enum(:each_block_deep) unless ruby_block
3750
+ # A ruby block?
3751
+ # Recurse on each argument.
3752
+ @args.each do |arg|
3753
+ if arg.respond_to?(:each_block_deep) then
3754
+ arg.each_block_deep(&ruby_block)
3755
+ end
3756
+ end
3757
+ end
3758
+
3759
+ # Iterates over all the statements contained in the current block.
3760
+ def each_statement_deep(&ruby_block)
3761
+ # No ruby block? Return an enumerator.
3762
+ return to_enum(:each_statement_deep) unless ruby_block
3763
+ # A ruby block?
3764
+ # Apply it on self.
3765
+ ruby_block.call(self)
3766
+ # Recurse on each argument.
3767
+ @args.each do |arg|
3768
+ if arg.respond_to?(:each_statement_deep) then
3769
+ arg.each_statement_deep(&ruby_block)
3770
+ end
3771
+ end
3772
+ end
3773
+
3774
+ end
3775
+
3776
+
3574
3777
  ##
3575
3778
  # Describes a wait statement: not synthesizable!
3576
3779
  class TimeWait < Statement
@@ -3867,7 +4070,6 @@ module HDLRuby::Low
3867
4070
  # No ruby block? Return an enumerator.
3868
4071
  return to_enum(:each_inner) unless ruby_block
3869
4072
  # A ruby block? Apply it on each inner signal instance.
3870
- # @inners.each_value(&ruby_block)
3871
4073
  @inners.each(&ruby_block)
3872
4074
  end
3873
4075
  alias_method :each_signal, :each_inner
@@ -3958,17 +4160,6 @@ module HDLRuby::Low
3958
4160
  def last_statement
3959
4161
  return @statements[-1]
3960
4162
  end
3961
-
3962
- # # Deletes +statement+.
3963
- # def delete_statement(statement)
3964
- # if @statements.include?(statement) then
3965
- # # Statement is present, delete it.
3966
- # @statements.delete(statement)
3967
- # # And remove its parent.
3968
- # statement.parent = nil
3969
- # end
3970
- # statement
3971
- # end
3972
4163
 
3973
4164
  # Iterates over the sub blocks.
3974
4165
  def each_block(&ruby_block)
@@ -4180,6 +4371,11 @@ module HDLRuby::Low
4180
4371
  return !self.leftvalue?
4181
4372
  end
4182
4373
 
4374
+ # Tells if the expression is immutable (cannot be written.)
4375
+ def immutable?
4376
+ false
4377
+ end
4378
+
4183
4379
  # Iterates over the expression children if any.
4184
4380
  def each_node(&ruby_block)
4185
4381
  # By default: no child.
@@ -4235,29 +4431,34 @@ module HDLRuby::Low
4235
4431
  # Describes a value.
4236
4432
  class Value < Expression
4237
4433
 
4238
- # Moved to Expression
4239
- # # The type of value.
4240
- # attr_reader :type
4241
-
4242
4434
  # The content of the value.
4243
4435
  attr_reader :content
4244
4436
 
4245
4437
  # Creates a new value typed +type+ and containing +content+.
4246
4438
  def initialize(type,content)
4247
- # Moved to Expression.
4248
- # # Check and set the type.
4249
- # if type.is_a?(Type) then
4250
- # @type = type
4251
- # else
4252
- # raise AnyError, "Invalid class for a type: #{type.class}."
4253
- # end
4254
4439
  super(type)
4255
- # Checks and set the content: Ruby Numeric and HDLRuby BitString
4256
- # are supported. Strings or equivalent are converted to BitString.
4257
- unless content.is_a?(Numeric) or content.is_a?(HDLRuby::BitString)
4258
- content = HDLRuby::BitString.new(content.to_s)
4440
+ unless content then
4441
+ # Handle the nil content case.
4442
+ unless type.eql?(Void) then
4443
+ raise AnyError, "A value with nil content must have the Void type."
4444
+ end
4445
+ @content = content
4446
+ else
4447
+ # Checks and set the content: Ruby Numeric and HDLRuby
4448
+ # BitString are supported. Strings or equivalent are
4449
+ # converted to BitString.
4450
+ unless content.is_a?(Numeric) or
4451
+ content.is_a?(HDLRuby::BitString)
4452
+ content = HDLRuby::BitString.new(content.to_s)
4453
+ end
4454
+ @content = content
4259
4455
  end
4260
- @content = content
4456
+ end
4457
+
4458
+ # Tells if the expression is immutable (cannot be written.)
4459
+ def immutable?
4460
+ # Values are always immutable.
4461
+ true
4261
4462
  end
4262
4463
 
4263
4464
  # Iterates over each object deeply.
@@ -4326,6 +4527,7 @@ module HDLRuby::Low
4326
4527
  end
4327
4528
  end
4328
4529
 
4530
+
4329
4531
  ##
4330
4532
  # Describes a cast.
4331
4533
  class Cast < Expression
@@ -4345,6 +4547,12 @@ module HDLRuby::Low
4345
4547
  child.parent = self
4346
4548
  end
4347
4549
 
4550
+ # Tells if the expression is immutable (cannot be written.)
4551
+ def immutable?
4552
+ # Immutable if the child is immutable.
4553
+ return child.immutable?
4554
+ end
4555
+
4348
4556
  # Iterates over each object deeply.
4349
4557
  #
4350
4558
  # Returns an enumerator if no ruby block is given.
@@ -4475,6 +4683,12 @@ module HDLRuby::Low
4475
4683
  child.parent = self
4476
4684
  end
4477
4685
 
4686
+ # Tells if the expression is immutable (cannot be written.)
4687
+ def immutable?
4688
+ # Immutable if the child is immutable.
4689
+ return child.immutable?
4690
+ end
4691
+
4478
4692
  # Iterates over each object deeply.
4479
4693
  #
4480
4694
  # Returns an enumerator if no ruby block is given.
@@ -4577,6 +4791,12 @@ module HDLRuby::Low
4577
4791
  left.parent = right.parent = self
4578
4792
  end
4579
4793
 
4794
+ # Tells if the expression is immutable (cannot be written.)
4795
+ def immutable?
4796
+ # Immutable if both children are immutable.
4797
+ return left.immutable? && right.immutable?
4798
+ end
4799
+
4580
4800
  # Iterates over each object deeply.
4581
4801
  #
4582
4802
  # Returns an enumerator if no ruby block is given.
@@ -4688,6 +4908,15 @@ module HDLRuby::Low
4688
4908
  end
4689
4909
  end
4690
4910
 
4911
+ # Tells if the expression is immutable (cannot be written.)
4912
+ def immutable?
4913
+ # Immutable if children are all immutable.
4914
+ return self.select.constant &&
4915
+ self.each_choice.reduce(true) do |r,c|
4916
+ r && c.immutable?
4917
+ end
4918
+ end
4919
+
4691
4920
  # Iterates over each object deeply.
4692
4921
  #
4693
4922
  # Returns an enumerator if no ruby block is given.
@@ -4822,6 +5051,14 @@ module HDLRuby::Low
4822
5051
  expressions.each { |expression| self.add_expression(expression) }
4823
5052
  end
4824
5053
 
5054
+ # Tells if the expression is immutable (cannot be written.)
5055
+ def immutable?
5056
+ # Immutable if children are all immutable.
5057
+ return self.each_expression.reduce(true) do |r,c|
5058
+ r && c.immutable?
5059
+ end
5060
+ end
5061
+
4825
5062
  # Iterates over each object deeply.
4826
5063
  #
4827
5064
  # Returns an enumerator if no ruby block is given.
@@ -4985,6 +5222,14 @@ module HDLRuby::Low
4985
5222
  refs.each { |ref| ref.parent = self }
4986
5223
  end
4987
5224
 
5225
+ # Tells if the expression is immutable (cannot be written.)
5226
+ def immutable?
5227
+ # Immutable if children are all immutable.
5228
+ return self.each_ref.reduce(true) do |r,c|
5229
+ r && c.immutable?
5230
+ end
5231
+ end
5232
+
4988
5233
  # Iterates over each object deeply.
4989
5234
  #
4990
5235
  # Returns an enumerator if no ruby block is given.
@@ -5102,6 +5347,12 @@ module HDLRuby::Low
5102
5347
  index.parent = self
5103
5348
  end
5104
5349
 
5350
+ # Tells if the expression is immutable (cannot be written.)
5351
+ def immutable?
5352
+ # Immutable if the ref is immutable.
5353
+ return self.ref.immutable?
5354
+ end
5355
+
5105
5356
  # Iterates over each object deeply.
5106
5357
  #
5107
5358
  # Returns an enumerator if no ruby block is given.
@@ -5215,6 +5466,12 @@ module HDLRuby::Low
5215
5466
  first.parent = last.parent = self
5216
5467
  end
5217
5468
 
5469
+ # Tells if the expression is immutable (cannot be written.)
5470
+ def immutable?
5471
+ # Immutable if the ref is immutable.
5472
+ return self.ref.immutable?
5473
+ end
5474
+
5218
5475
  # Iterates over each object deeply.
5219
5476
  #
5220
5477
  # Returns an enumerator if no ruby block is given.
@@ -5444,4 +5701,135 @@ module HDLRuby::Low
5444
5701
  return super
5445
5702
  end
5446
5703
  end
5704
+
5705
+
5706
+
5707
+ ##
5708
+ # Describes a string.
5709
+ #
5710
+ # NOTE: This is not synthesizable!
5711
+ class StringE < Expression
5712
+
5713
+ attr_reader :content
5714
+
5715
+ # Creates a new string whose content is +str+ and is modified using
5716
+ # the objects of +args+.
5717
+ def initialize(content,*args)
5718
+ super(StringT)
5719
+ # Checks and set the content.
5720
+ @content = content.to_s
5721
+ # Process the arguments.
5722
+ @args = args.map do |arg|
5723
+ arg.parent = self
5724
+ arg
5725
+ end
5726
+ end
5727
+
5728
+ # Tells if the expression is immutable (cannot be written.)
5729
+ def immutable?
5730
+ # String objects are always immutable.
5731
+ true
5732
+ end
5733
+
5734
+ # Comparison for hash: structural comparison.
5735
+ def eql?(obj)
5736
+ return false unless obj.is_a?(StringE)
5737
+ return false unless @content.eql?(obj.content)
5738
+ return false if @args.each.zip(obj.each_arg).any? do |a0,a1|
5739
+ !a0.eql?(a1)
5740
+ end
5741
+ return true
5742
+ end
5743
+
5744
+ # Iterates over each argument.
5745
+ #
5746
+ # Returns an enumerator if no ruby block is given.
5747
+ def each_arg(&ruby_block)
5748
+ # No ruby block? Return an enumerator.
5749
+ return to_enum(:each_arg) unless ruby_block
5750
+ # A ruby block? First apply it to each argument.
5751
+ @args.each(&ruby_block)
5752
+ end
5753
+
5754
+ # Iterates over each object deeply.
5755
+ #
5756
+ # Returns an enumerator if no ruby block is given.
5757
+ def each_deep(&ruby_block)
5758
+ # No ruby block? Return an enumerator.
5759
+ return to_enum(:each_deep) unless ruby_block
5760
+ # A ruby block? First apply it to current.
5761
+ ruby_block.call(self)
5762
+ # Then apply on the arguments.
5763
+ self.each_arg(&ruby_block)
5764
+ end
5765
+
5766
+ # Hash function.
5767
+ def hash
5768
+ return @args.hash
5769
+ end
5770
+
5771
+ # Clones the string.
5772
+ def clone
5773
+ return StringE.new(@content.clone,*@args.map {|arg| arg.clone})
5774
+ end
5775
+
5776
+ # Iterates over the expression children if any.
5777
+ def each_node(&ruby_block)
5778
+ # No ruby block? Return an enumerator.
5779
+ return to_enum(:each_node) unless ruby_block
5780
+ # A ruby block?
5781
+ # Apply it on each argument.
5782
+ @args.each(&ruby_block)
5783
+ end
5784
+
5785
+ # Iterates over the nodes deeply if any.
5786
+ def each_node_deep(&ruby_block)
5787
+ # No ruby block? Return an enumerator.
5788
+ return to_enum(:each_node_deep) unless ruby_block
5789
+ # A ruby block? First apply it to current.
5790
+ ruby_block.call(self)
5791
+ # And apply it on each argument.
5792
+ @args.each(&ruby_block)
5793
+ end
5794
+
5795
+ # Iterates over the sub blocks.
5796
+ def each_block(&ruby_block)
5797
+ # No ruby block? Return an enumerator.
5798
+ return to_enum(:each_block) unless ruby_block
5799
+ # A ruby block?
5800
+ # Recurse on each argument.
5801
+ @args.each do |arg|
5802
+ arg.each_block(&ruby_block) if arg.respond_to?(:each_block)
5803
+ end
5804
+ end
5805
+
5806
+ # Iterates over all the blocks contained in the current block.
5807
+ def each_block_deep(&ruby_block)
5808
+ # No ruby block? Return an enumerator.
5809
+ return to_enum(:each_block_deep) unless ruby_block
5810
+ # A ruby block?
5811
+ # Recurse on each argument.
5812
+ @args.each do |arg|
5813
+ if arg.respond_to?(:each_block_deep) then
5814
+ arg.each_block_deep(&ruby_block)
5815
+ end
5816
+ end
5817
+ end
5818
+
5819
+ # Iterates over all the statements contained in the current block.
5820
+ def each_statement_deep(&ruby_block)
5821
+ # No ruby block? Return an enumerator.
5822
+ return to_enum(:each_statement_deep) unless ruby_block
5823
+ # A ruby block?
5824
+ # Apply it on self.
5825
+ ruby_block.call(self)
5826
+ # Recurse on each argument.
5827
+ @args.each do |arg|
5828
+ if arg.respond_to?(:each_statement_deep) then
5829
+ arg.each_statement_deep(&ruby_block)
5830
+ end
5831
+ end
5832
+ end
5833
+
5834
+ end
5447
5835
  end