Class: HDLRuby::Low::Unary

Inherits:
Operation show all
Includes:
OneChildMutable
Defined in:
lib/HDLRuby/hruby_db.rb,
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_low2c.rb,
lib/HDLRuby/hruby_low2hdr.rb,
lib/HDLRuby/hruby_low2vhd.rb,
lib/HDLRuby/hruby_verilog.rb,
lib/HDLRuby/hruby_low2high.rb,
lib/HDLRuby/hruby_low_mutable.rb,
lib/HDLRuby/hruby_low_skeleton.rb,
lib/HDLRuby/hruby_low_fix_types.rb,
lib/HDLRuby/hruby_low_with_bool.rb,
lib/HDLRuby/hruby_low_bool2select.rb,
lib/HDLRuby/hruby_low_casts_without_expression.rb

Overview

Extends the Unary class with functionality for extracting expressions from cast.

Direct Known Subclasses

High::Unary

Constant Summary

Constants included from Low2Symbol

Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable

Instance Attribute Summary collapse

Attributes inherited from Operation

#operator

Attributes inherited from Expression

#type

Attributes included from Hparent

#parent

Instance Method Summary collapse

Methods included from OneChildMutable

#map_nodes!, #replace_expressions!, #set_child!

Methods inherited from Operation

#set_operator!

Methods inherited from Expression

#break_types!, #extract_selects_to!, #leftvalue?, #map_nodes!, #replace_expressions!, #replace_names!, #rightvalue?, #set_type!, #statement

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#scope

Constructor Details

#initialize(type, operator, child) ⇒ Unary

Creates a new unary expression with +type+ applying +operator+ on +child+ expression. def initialize(operator,child)



4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
# File 'lib/HDLRuby/hruby_low.rb', line 4673

def initialize(type,operator,child)
    # Initialize as a general operation.
    super(type,operator)
    # Check and set the child.
    unless child.is_a?(Expression)
        raise AnyError,
              "Invalid class for an expression: #{child.class}"
    end
    @child = child
    # And set its parent.
    child.parent = self
end

Instance Attribute Details

#childObject (readonly)

The child.



4668
4669
4670
# File 'lib/HDLRuby/hruby_low.rb', line 4668

def child
  @child
end

Instance Method Details

#boolean?Boolean

Tells if the expression is boolean.

Returns:

  • (Boolean)


107
108
109
# File 'lib/HDLRuby/hruby_low_with_bool.rb', line 107

def boolean?
    return self.child.boolean?
end

#boolean_in_assign2selectObject

Converts booleans in assignments to select operators.



197
198
199
200
201
202
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 197

def boolean_in_assign2select
    # Recurse on the sub node.
    return Unary.new(self.type,self.operator,
                     self.child.boolean_in_assign2select)
    return self
end

#casts_without_expression!Object

Extracts the expressions from the casts.



226
227
228
229
230
231
232
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 226

def casts_without_expression!
    # # Recurse on the sub node.
    # return Unary.new(self.type,self.operator,
    #                  self.child.casts_without_expression)
    self.set_child!(self.child.casts_without_expression!)
    return self
end

#cloneObject

Clones the unary operator (deeply)



4760
4761
4762
# File 'lib/HDLRuby/hruby_low.rb', line 4760

def clone
    return Unary.new(@type,self.operator,@child.clone)
end

#each_deep(&ruby_block) ⇒ Object

Iterates over each object deeply.

Returns an enumerator if no ruby block is given.



4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
# File 'lib/HDLRuby/hruby_low.rb', line 4695

def each_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_deep) unless ruby_block
    # A ruby block? First apply it to current.
    ruby_block.call(self)
    # Then apply on the type.
    self.type.each_deep(&ruby_block)
    # Then apply on the child.
    self.child.each_deep(&ruby_block)
end

#each_node(&ruby_block) ⇒ Object Also known as: each_expression

Iterates over the expression children if any.



4722
4723
4724
4725
4726
4727
# File 'lib/HDLRuby/hruby_low.rb', line 4722

def each_node(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_node) unless ruby_block
    # A ruby block? Apply it on the child.
    ruby_block.call(@child)
end

#each_node_deep(&ruby_block) ⇒ Object

Iterates over the nodes deeply if any.



4732
4733
4734
4735
4736
4737
4738
4739
# File 'lib/HDLRuby/hruby_low.rb', line 4732

def each_node_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_node_deep) unless ruby_block
    # A ruby block? First apply it to current.
    ruby_block.call(self)
    # And recurse on the child.
    @child.each_node_deep(&ruby_block)
end

#each_ref_deep(&ruby_block) ⇒ Object

Iterates over all the references encountered in the expression.

NOTE: do not iterate inside the references.



4744
4745
4746
4747
4748
4749
4750
4751
# File 'lib/HDLRuby/hruby_low.rb', line 4744

def each_ref_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_ref_deep) unless ruby_block
    # puts "each_ref_deep for Unary"
    # A ruby block?
    # Recurse on the child.
    @child.each_ref_deep(&ruby_block)
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:

  • (Boolean)


4707
4708
4709
4710
4711
4712
4713
4714
# File 'lib/HDLRuby/hruby_low.rb', line 4707

def eql?(obj)
    # General comparison.
    return false unless super(obj)
    # Specific comparison.
    return false unless obj.is_a?(Unary)
    return false unless @child.eql?(obj.child)
    return true
end

#explicit_types(type = nil) ⇒ Object

Explicit the types conversions in the unary operation where +type+ is the expected type of the condition if any.



249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 249

def explicit_types(type = nil)
    # Recurse on the child (no type to specify here, unary operations
    # preserve the type of their child).
    op = Unary.new(self.type,self.operator,self.child.explicit_types)
    # Does the type match the operation?
    if type && !self.type.eql?(type) then
        # No create a cast.
        return Cast.new(type,op)
    else
        # Yes, return the operation as is.
        return op
    end
end

#hashObject

Hash function.



4717
4718
4719
# File 'lib/HDLRuby/hruby_low.rb', line 4717

def hash
    return [super,@child].hash
end

#immutable?Boolean

Tells if the expression is immutable (cannot be written.)

Returns:

  • (Boolean)


4687
4688
4689
4690
# File 'lib/HDLRuby/hruby_low.rb', line 4687

def immutable?
    # Immutable if the child is immutable.
    return child.immutable?
end

#to_c(level = 0) ⇒ Object

Generates the C text of the equivalent HDLRuby code. +level+ is the hierachical level of the object.



1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
# File 'lib/HDLRuby/hruby_low2c.rb', line 1655

def to_c(level = 0)
    res = "({\n"
    # Overrides the upper src0 and dst...
    res << (" " * ((level+1)*3))
    res << "Value src0, dst;\n"
    if (self.operator != :+@) then
        # And allocates a new value for dst unless the operator
        # is +@ that does not compute anything.
        res << (" " * ((level+1)*3))
        res << "dst = get_value();\n"
    end
    # Save the state of the value pool.
    res << (" " * ((level+1)*3))
    res << "unsigned int pool_state = get_value_pos();\n"
    # Compute the child.
    res << (" " * ((level+1)*3))
    res << "src0 = #{self.child.to_c(level+2)};\n"
    res << (" " * ((level+1)*3))
    case self.operator
    when :~ then
        res += "dst = not_value(src0,dst);\n"
    when :-@ then
        res += "dst = neg_value(src0,dst);\n"
    when :+@ then
        res += "dst = #{self.child.to_c(level)};\n"
    else
        raise "Invalid unary operator: #{self.operator}."
    end
    # Restore the value pool state.
    res << (" " * ((level+1)*3))
    res << "set_value_pos(pool_state);\n"
    # Close the computation
    res << (" " * (level*3))
    res << "dst; })"

    return res
end

#to_hdr(level = 0) ⇒ Object

Generates the text of the equivalent hdr text. +level+ is the hierachical level of the object.



589
590
591
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 589

def to_hdr(level = 0)
    return "(#{self.operator.to_s[0]}" + self.child.to_hdr(level) + ")"
end

#to_highObject

Creates a new high unary expression.



416
417
418
419
# File 'lib/HDLRuby/hruby_low2high.rb', line 416

def to_high
    return HDLRuby::High::Unary.new(self.type.to_high,self.operator,
                                    self.child.to_high)
end

#to_verilogObject

Converts the system to Verilog code.



1629
1630
1631
# File 'lib/HDLRuby/hruby_verilog.rb', line 1629

def to_verilog
    return "#{self.operator[0]}#{self.child.to_verilog}"
end

#to_vhdl(level = 0, std_logic = false) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object. +std_logic+ tells if std_logic computation is to be done.



1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1248

def to_vhdl(level = 0, std_logic = false)
    # Generate the operator string.
    operator = self.operator == :~ ? "not " : self.operator.to_s[0]
    # Is the operator arithmetic?
    if [:+@, :-@].include?(self.operator) then
        # Yes, type conversion my be required by VHDL standard.
        res = "#{Low2VHDL.unarith_cast(self)}(#{operator}" +
                     Low2VHDL.to_arith(self.child) + ")"
        res += "(0)" if std_logic
        return res
    else
        # No, generate simply the unary operation.
        # (The other unary operator is logic, no need to force
        # std_logic.)
        return "(#{operator}" + self.child.to_vhdl(level,std_logic) + ")"
    end
end

#use_name?(*names) ⇒ Boolean

Tell if the expression includes a signal whose name is one of +names+.

Returns:

  • (Boolean)


4754
4755
4756
4757
# File 'lib/HDLRuby/hruby_low.rb', line 4754

def use_name?(*names)
    # Recurse on the child.
    return @child.use_name?(*names)
end