Class: HDLRuby::Low::Expression

Inherits:
Object
  • Object
show all
Includes:
Hparent, Low2Symbol
Defined in:
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_low2c.rb,
lib/HDLRuby/hruby_low2hdr.rb,
lib/HDLRuby/hruby_low2sym.rb,
lib/HDLRuby/hruby_low2vhd.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_without_select.rb,
lib/HDLRuby/hruby_low_without_namespace.rb,
lib/HDLRuby/hruby_low_without_subsignals.rb

Overview

Describes an expression.

NOTE: this is an abstract class which is not to be used directly.

Direct Known Subclasses

Cast, Concat, Operation, Ref, StringE, Value

Constant Summary

Constants included from Low2Symbol

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

Instance Attribute Summary collapse

Attributes included from Hparent

#parent

Instance Method Summary collapse

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#hierarchy, #no_parent!, #scope

Constructor Details

#initialize(type = Void) ⇒ Expression

Creates a new Expression with +type+



4751
4752
4753
4754
4755
4756
4757
4758
# File 'lib/HDLRuby/hruby_low.rb', line 4751

def initialize(type = Void)
    # Check and set the type.
    if type.is_a?(Type) then
        @type = type
    else
        raise AnyError, "Invalid class for a type: #{type.class}."
    end
end

Instance Attribute Details

#typeObject (readonly)

Gets the type of the expression.

def type # By default: the void type. return Void end



4748
4749
4750
# File 'lib/HDLRuby/hruby_low.rb', line 4748

def type
  @type
end

Instance Method Details

#boolean?Boolean

Tells if the expression is boolean.

Returns:

  • (Boolean)


109
110
111
# File 'lib/HDLRuby/hruby_low_with_bool.rb', line 109

def boolean?
    return false
end

#break_types!(types) ⇒ Object

Breaks the hierarchical types into sequences of type definitions. Assumes to_upper_space! has been called before. +types+ include the resulting types.



521
522
523
524
525
526
527
528
529
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 521

def break_types!(types)
    self.each_node do |node|
        # Need to break only in the case of a cast.
        if node.is_a?(Cast) then
            # node.type.break_types!(types)
            node.set_type!(node.type.break_types!(types))
        end
    end
end

#cloneObject

Clones the expression (deeply)

Raises:



4849
4850
4851
4852
# File 'lib/HDLRuby/hruby_low.rb', line 4849

def clone
    raise AnyError,
          "Internal error: clone not defined for class: #{self.class}"
end

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

Iterates over the expression children if any.



4806
4807
4808
# File 'lib/HDLRuby/hruby_low.rb', line 4806

def each_node(&ruby_block)
    # By default: no child.
end

#each_node_deep(&ruby_block) ⇒ Object

Iterates over the nodes deeply if any.



4813
4814
4815
4816
4817
4818
4819
# File 'lib/HDLRuby/hruby_low.rb', line 4813

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 that's all.
end

#each_ref_deep(&ruby_block) ⇒ Object

Iterates over all the references encountered in the expression.

NOTE: do not iterate inside the references.



4824
4825
4826
4827
4828
4829
4830
4831
# File 'lib/HDLRuby/hruby_low.rb', line 4824

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 Expression which is:#{self}"
    # A ruby block?
    # If the expression is a reference, applies ruby_block on it.
    ruby_block.call(self) if self.is_a?(Ref)
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:

  • (Boolean)


4764
4765
4766
4767
4768
# File 'lib/HDLRuby/hruby_low.rb', line 4764

def eql?(obj)
    return false unless obj.is_a?(Expression)
    return false unless @type.eql?(obj.type)
    return true
end

#explicit_types(type = nil) ⇒ Object

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



232
233
234
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 232

def explicit_types(type = nil)
    raise "Should implement explicit_types for class #{self.class}."
end

#extract_selects_to!(selects) ⇒ Object

Extract the Select expressions and put them into +selects+



252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/HDLRuby/hruby_low_without_select.rb', line 252

def extract_selects_to!(selects)
    # Recurse on the sub expressions.
    self.map_expressions! {|expr| expr.extract_selects_to!(selects) }
    # Treat case of select.
    if self.is_a?(Select) then
        # Create the signal replacing self.
        sig = SignalI.new(HDLRuby.uniq_name,self.type)
        # Add the self with replacing sig to the extracted selects
        selects << [self,sig]
        # Create the signal replacing self.
        blk = self.statement.block
        if blk then
            # Add the signal in the block.
            blk.add_inner(sig)
        else
            # No block, this is a connection, add the signal in the
            # socpe
            self.statement.scope.add_inner(sig)
        end
        # And return a reference to it.
        return RefName.new(sig.type,RefThis.new,sig.name)
    end
    return self
end

#hashObject

Hash function.



4771
4772
4773
# File 'lib/HDLRuby/hruby_low.rb', line 4771

def hash
    return [@type].hash
end

#immutable?Boolean

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

Returns:

  • (Boolean)


4801
4802
4803
# File 'lib/HDLRuby/hruby_low.rb', line 4801

def immutable?
    false
end

#leftvalue?Boolean

Tells if the expression is a left value of an assignment.

Returns:

  • (Boolean)


4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
# File 'lib/HDLRuby/hruby_low.rb', line 4776

def leftvalue?
    # Maybe its the left of a left value.
    if parent.respond_to?(:leftvalue?) && parent.leftvalue? then
        # Yes so it is also a left value if it is a sub ref.
        if parent.respond_to?(:ref) then
            # It might nor be a sub ref.
            # return parent.ref.eql?(self)
            return parent.ref.equal?(self)
        else
            # It is necessarily a sub ref (case of RefConcat for now).
            return true
        end
    end
    # No, therefore maybe it is directly a left value.
    return (parent.is_a?(Transmit) || parent.is_a?(Connection)) &&
        # parent.left.eql?(self)
        parent.left.equal?(self)
end

#map_nodes!(&ruby_block) ⇒ Object Also known as: map_expressions!

Maps on the children.



1321
1322
1323
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1321

def map_nodes!(&ruby_block)
    # By default, nothing to do.
end

#replace_expressions!(node2rep) ⇒ Object

Replaces sub expressions using +node2rep+ table indicating the node to replace and the corresponding replacement. Returns the actually replaced nodes and their corresponding replacement.

NOTE: the replacement is duplicated.



1333
1334
1335
1336
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1333

def replace_expressions!(node2rep)
    # By default, nothing to do.
    return {}
end

#replace_names!(former, nname) ⇒ Object

Replaces recursively +former+ name by +nname+ until it is redeclared.



509
510
511
512
513
514
515
516
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 509

def replace_names!(former,nname)
    # By default: try to replace the name recursively.
    self.each_node_deep do |node|
        if node.respond_to?(:name) && node.name == former then
            node.set_name!(nname)
        end
    end
end

#rightvalue?Boolean

Tells if the expression is a right value.

Returns:

  • (Boolean)


4796
4797
4798
# File 'lib/HDLRuby/hruby_low.rb', line 4796

def rightvalue?
    return !self.leftvalue?
end

#set_type!(type) ⇒ Object

Sets the type.



1311
1312
1313
1314
1315
1316
1317
1318
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1311

def set_type!(type)
    # Check and set the type.
    if type.is_a?(Type) then
        @type = type
    else
        raise AnyError, "Invalid class for a type: #{type.class}."
    end
end

#signal2subs!Object

Decompose the hierarchical signals in the statements.



216
217
218
219
220
221
# File 'lib/HDLRuby/hruby_low_without_subsignals.rb', line 216

def signal2subs!
    # puts "signal2subs! for expr=#{self}"
    # Recurse on the subexpressions.
    self.map_expressions!(&:signal2subs!)
    return self
end

#statementObject

Get the statement of the expression.



4834
4835
4836
4837
4838
4839
4840
# File 'lib/HDLRuby/hruby_low.rb', line 4834

def statement
    if self.parent.is_a?(Statement)
        return self.parent
    else
        return self.parent.statement
    end
end

#to_c(res, level = 0) ⇒ Object

Generates the C text of the equivalent HDLRuby code. +level+ is the hierachical level of the object. def to_c(level = 0)

Raises:



2119
2120
2121
2122
# File 'lib/HDLRuby/hruby_low2c.rb', line 2119

def to_c(res,level = 0)
    # Should never be here.
    raise AnyError, "Internal error: to_c should be implemented in class :#{self.class}"
end

#to_c_expr(res, level = 0) ⇒ Object

Generates the C text for an expression access to the expression, default case. +level+ is the hierachical level of the object.



2127
2128
2129
2130
2131
2132
# File 'lib/HDLRuby/hruby_low2c.rb', line 2127

def to_c_expr(res,level = 0)
    res << "({"
    self.to_c(res,level+1)
    res << (" " * ((level+1)*3))
    res << "pop();})"
end

#to_hdr(level = 0) ⇒ Object

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

Raises:



555
556
557
558
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 555

def to_hdr(level = 0)
    # Should never be here.
    raise AnyError, "Internal error: to_high should be implemented in class :#{self.class}"
end

#to_highObject

Creates a new high expression.

Raises:



404
405
406
407
# File 'lib/HDLRuby/hruby_low2high.rb', line 404

def to_high
    raise AnyError,
          "Internal error: to_high is not defined for class: #{self.class}"
end

#to_vhdl(level = 0) ⇒ Object

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

Raises:



1167
1168
1169
1170
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1167

def to_vhdl(level = 0)
    # Should never be here.
    raise AnyError, "Internal error: to_vhdl should be implemented in class :#{self.class}"
end

#use_name?(*names) ⇒ Boolean

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

Returns:

  • (Boolean)


4843
4844
4845
4846
# File 'lib/HDLRuby/hruby_low.rb', line 4843

def use_name?(*names)
    # By default nothing.
    return false
end