HDLRuby 2.5.1 → 2.6.8

Sign up to get free protection for your applications and to get access to all the features.
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